Program.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. // Copyright (c) 2012-2020 fo-dicom contributors.
  2. // Licensed under the Microsoft Public License (MS-PL).
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Threading.Tasks;
  7. using Dicom;
  8. using Dicom.Log;
  9. using Dicom.Network;
  10. using DicomClient = Dicom.Network.Client.DicomClient;
  11. namespace Worklist_SCU
  12. {
  13. public static class Program
  14. {
  15. private const string _performedStationAETitle = "Modality";
  16. private const string _performedStationName = "Modality";
  17. [Obsolete]
  18. public static async Task Main(string[] args)
  19. {
  20. // Initialize log manager.
  21. //NetworkManager.SetImplementation(new DesktopNetworkManager());
  22. //Dicom.IO.IOManager.SetImplementation(new Dicom.IO.DesktopIOManager());
  23. NetworkManager.SetImplementation(new DesktopNetworkManager());
  24. Dicom.IO.IOManager.SetImplementation(new Dicom.IO.DesktopIOManager());
  25. LogManager.SetImplementation(ConsoleLogManager.Instance);
  26. // set the connection parameters
  27. //var serverIP = "127.0.0.1";
  28. //var serverPort = 108;
  29. //var serverAET = "ZSKKCT";
  30. //var clientAET = "ZSKKCT";
  31. var serverIP = System.Configuration.ConfigurationSettings.AppSettings["IP"];
  32. var serverPort = int.Parse(System.Configuration.ConfigurationSettings.AppSettings["Port"]);
  33. var serverAET = System.Configuration.ConfigurationSettings.AppSettings["serverAET"];
  34. var clientAET = System.Configuration.ConfigurationSettings.AppSettings["clientAET"];
  35. //var serverIP = ConfigurationManager.AppSettings["IP"];
  36. //var serverPort = ConfigurationManager.AppSettings["Port"];
  37. //var serverAET = ConfigurationManager.AppSettings["serverAET"];
  38. //var clientAET = ConfigurationManager.AppSettings["clientAET"];
  39. // query all worklist items from worklist server
  40. var worklistItems = await GetAllItemsFromWorklistAsync(serverIP, serverPort, serverAET, clientAET);
  41. Console.WriteLine($"received {worklistItems.Count} worklist items.");
  42. // take the first result and set it to in-progress via mpps
  43. var worklistItem = worklistItems.First();
  44. var (affectedInstanceUid, responseStatus, responseMessage) = await SendMppsInProgressAsync(serverIP, serverPort, serverAET, clientAET, worklistItem);
  45. Console.WriteLine($"in progress sent with response {responseStatus} ({responseMessage})");
  46. // then send the compleded
  47. var responseCompleted = await SendMppsCompletedAsync(serverIP, serverPort, serverAET, clientAET, affectedInstanceUid, worklistItem);
  48. Console.WriteLine($"completed sent with response {responseCompleted.responseStatus} ({responseCompleted.responseMessage})");
  49. Console.ReadLine();
  50. }
  51. private static async Task<(string responseStatus, string responseMessage)> SendMppsCompletedAsync(string serverIP, int serverPort, string serverAET, string clientAET, DicomUID affectedInstanceUid, DicomDataset worklistItem)
  52. {
  53. var client = new DicomClient(serverIP, serverPort, false, clientAET, serverAET);
  54. var dataset = new DicomDataset();
  55. DicomSequence procedureStepSq = worklistItem.GetSequence(DicomTag.ScheduledProcedureStepSequence);
  56. // A worklistitem may have a list of scheduledprocedureSteps.
  57. // For each of them you have to send separate MPPS InProgress- and Completed-messages.
  58. // there in this example we will only send for the first procedure step
  59. var procedureStep = procedureStepSq.First();
  60. // data
  61. dataset.Add(DicomTag.PerformedProcedureStepEndDate, DateTime.Now);
  62. dataset.Add(DicomTag.PerformedProcedureStepEndTime, DateTime.Now);
  63. dataset.Add(DicomTag.PerformedProcedureStepStatus, "COMPLETED");
  64. dataset.Add(DicomTag.PerformedProcedureStepDescription, procedureStep.GetSingleValueOrDefault(DicomTag.ScheduledProcedureStepID, string.Empty));
  65. dataset.Add(DicomTag.PerformedProcedureTypeDescription, string.Empty);
  66. dataset.Add(DicomTag.PerformedProtocolCodeSequence, new DicomDataset());
  67. // dose and reports
  68. dataset.Add(DicomTag.ImageAndFluoroscopyAreaDoseProduct, 0.0m); // if there has bee sone dose while examination
  69. dataset.Add(DicomTag.CommentsOnRadiationDose, string.Empty); // a free text that contains all dose parameters
  70. // images created
  71. var performedSeriesSq = new DicomSequence(DicomTag.PerformedSeriesSequence);
  72. // iterate all Series that have been created while examination
  73. var serie = new DicomDataset
  74. {
  75. { DicomTag.RetrieveAETitle, string.Empty }, // the aetitle of the archive where the images have been sent to
  76. { DicomTag.SeriesDescription, "serie 1" },
  77. { DicomTag.PerformingPhysicianName, string.Empty },
  78. { DicomTag.OperatorsName, string.Empty },
  79. { DicomTag.ProtocolName, string.Empty },
  80. { DicomTag.SeriesInstanceUID, DicomUID.Generate() }
  81. };
  82. var refImagesInSerie = new DicomSequence(DicomTag.ReferencedImageSequence);
  83. // iterate all images in the serie
  84. var image = new DicomDataset
  85. {
  86. { DicomTag.ReferencedSOPClassUID, DicomUID.SecondaryCaptureImageStorage },
  87. { DicomTag.ReferencedSOPInstanceUID, DicomUID.Generate() }
  88. };
  89. refImagesInSerie.Items.Add(image);
  90. serie.Add(refImagesInSerie);
  91. performedSeriesSq.Items.Add(serie);
  92. dataset.Add(performedSeriesSq);
  93. var dicomFinished = new DicomNSetRequest(DicomUID.ModalityPerformedProcedureStepSOPClass, affectedInstanceUid)
  94. {
  95. Dataset = dataset
  96. };
  97. string responseStatus = string.Empty;
  98. string responseMessage = string.Empty;
  99. dicomFinished.OnResponseReceived += (req, response) =>
  100. {
  101. if (response != null)
  102. {
  103. Console.WriteLine(response);
  104. responseStatus = response.Status.ToString();
  105. responseMessage = response.ToString();
  106. }
  107. };
  108. await client.AddRequestAsync(dicomFinished);
  109. await client.SendAsync();
  110. return (responseStatus, responseMessage);
  111. }
  112. private static async Task<(DicomUID affectedInstanceUid, string responseStatus, string responseMessage)> SendMppsInProgressAsync(string serverIP, int serverPort, string serverAET, string clientAET, DicomDataset worklistItem)
  113. {
  114. var client = new DicomClient(serverIP, serverPort, false, clientAET, serverAET);
  115. var dataset = new DicomDataset();
  116. DicomSequence procedureStepSq = worklistItem.GetSequence(DicomTag.ScheduledProcedureStepSequence);
  117. // A worklistitem may have a list of scheduledprocedureSteps.
  118. // For each of them you have to send separate MPPS InProgress- and Completed-messages.
  119. // there in this example we will only send for the first procedure step
  120. var procedureStep = procedureStepSq.First();
  121. var content = new DicomDataset();
  122. // get study instance UID from MWL query resault
  123. string studyInstanceUID = worklistItem.GetSingleValueOrDefault(DicomTag.StudyInstanceUID, DicomUID.Generate().ToString());
  124. // set Attribute Sequence data
  125. content.Add(DicomTag.StudyInstanceUID, studyInstanceUID);
  126. content.Add(DicomTag.ReferencedStudySequence, new DicomDataset());
  127. content.Add(DicomTag.AccessionNumber, worklistItem.GetSingleValueOrDefault(DicomTag.AccessionNumber, string.Empty));
  128. content.Add(DicomTag.RequestedProcedureID, worklistItem.GetSingleValueOrDefault(DicomTag.RequestedProcedureID, string.Empty));
  129. content.Add(DicomTag.RequestedProcedureDescription, worklistItem.GetSingleValueOrDefault(DicomTag.RequestedProcedureDescription, string.Empty));
  130. content.Add(DicomTag.ScheduledProcedureStepID, procedureStep.GetSingleValueOrDefault(DicomTag.ScheduledProcedureStepID, string.Empty));
  131. content.Add(DicomTag.ScheduledProcedureStepDescription, procedureStep.GetSingleValueOrDefault(DicomTag.ScheduledProcedureStepDescription, string.Empty));
  132. content.Add(DicomTag.ScheduledProtocolCodeSequence, new DicomDataset());
  133. var attr_Sequence = new DicomSequence(DicomTag.ScheduledStepAttributesSequence, content);//"Scheduled Step Attribute Sequence"
  134. dataset.Add(attr_Sequence);
  135. dataset.Add(DicomTag.PatientName, worklistItem.GetSingleValueOrDefault(DicomTag.PatientName, string.Empty));
  136. dataset.Add(DicomTag.PatientID, worklistItem.GetSingleValueOrDefault(DicomTag.PatientID, string.Empty));
  137. dataset.Add(DicomTag.PatientBirthDate, worklistItem.GetSingleValueOrDefault(DicomTag.PatientBirthDate, string.Empty));
  138. dataset.Add(DicomTag.PatientSex, worklistItem.GetSingleValueOrDefault(DicomTag.PatientSex, string.Empty));
  139. dataset.Add(DicomTag.ReferencedPatientSequence, new DicomDataset());
  140. dataset.Add(DicomTag.PerformedProcedureStepID, procedureStep.GetSingleValueOrDefault(DicomTag.ScheduledProcedureStepID, string.Empty));
  141. dataset.Add(DicomTag.PerformedStationAETitle, _performedStationAETitle);
  142. dataset.Add(DicomTag.PerformedStationName, _performedStationName);
  143. dataset.Add(DicomTag.PerformedLocation, string.Empty);
  144. dataset.Add(DicomTag.PerformedProcedureStepStartDate, DateTime.Now);
  145. dataset.Add(DicomTag.PerformedProcedureStepStartTime, DateTime.Now);
  146. // set status
  147. dataset.Add(DicomTag.PerformedProcedureStepStatus, "IN PROGRESS");
  148. dataset.Add(DicomTag.PerformedProcedureStepDescription, procedureStep.GetSingleValueOrDefault(DicomTag.ScheduledProcedureStepID, string.Empty));
  149. dataset.Add(DicomTag.PerformedProcedureTypeDescription, string.Empty);
  150. dataset.Add(DicomTag.PerformedProcedureStepEndDate, string.Empty);
  151. dataset.Add(DicomTag.PerformedProcedureStepEndTime, string.Empty);
  152. // get modality from MWL query resault
  153. dataset.Add(DicomTag.Modality, procedureStep.GetSingleValueOrDefault(DicomTag.Modality, string.Empty));
  154. dataset.Add(DicomTag.StudyID, worklistItem.GetSingleValueOrDefault(DicomTag.StudyID, string.Empty));
  155. dataset.Add(DicomTag.PerformedProtocolCodeSequence, new DicomDataset());
  156. // create an unique UID as the effectedinstamceUid, this id will be needed for the N-SET also
  157. var effectedinstamceUid = DicomUID.Generate();
  158. var dicomStartRequest = new DicomNCreateRequest(DicomUID.ModalityPerformedProcedureStepSOPClass, effectedinstamceUid)
  159. {
  160. Dataset = dataset
  161. };
  162. string responseStatus = string.Empty;
  163. string responseMessage = string.Empty;
  164. dicomStartRequest.OnResponseReceived += (req, response) =>
  165. {
  166. if (response != null)
  167. {
  168. Console.WriteLine(response);
  169. responseStatus = response.Status.ToString();
  170. responseMessage = response.ToString();
  171. }
  172. };
  173. await client.AddRequestAsync(dicomStartRequest);
  174. await client.SendAsync();
  175. return (effectedinstamceUid, responseStatus, responseMessage);
  176. }
  177. private static async Task<List<DicomDataset>> GetAllItemsFromWorklistAsync(string serverIP, int serverPort, string serverAET, string clientAET)
  178. {
  179. var worklistItems = new List<DicomDataset>();
  180. var cfind = DicomCFindRequest.CreateWorklistQuery(); // no filter, so query all awailable entries
  181. cfind.OnResponseReceived = (DicomCFindRequest rq, DicomCFindResponse rp) =>
  182. {
  183. if (rp.HasDataset)
  184. {
  185. Console.WriteLine("Study UID: {0}", rp.Dataset.GetSingleValue<string>(DicomTag.StudyInstanceUID));
  186. worklistItems.Add(rp.Dataset);
  187. }
  188. else
  189. {
  190. Console.WriteLine(rp.Status.ToString());
  191. }
  192. };
  193. var client = new DicomClient(serverIP, serverPort, false, clientAET, serverAET);
  194. await client.AddRequestAsync(cfind);
  195. await client.SendAsync();
  196. return worklistItems;
  197. }
  198. }
  199. }