Article
· Apr 10, 2023 5m read

Receiving DICOM messages from PACS to IRIS for Health

In our previous article we saw how to capture DICOM type files located in a folder in our server and how we could send them to a PACS software (in our case the ORTHANC open source solution) for storage and consultation. Well, in this article we are going to deal with the opposite movement.

In our example, we are going to configure our IRIS for Health production to receive images sent from our PACS via TCP/IP. To do this, we must include a Business Service of the standard EnsLib.DICOM.Service.TCP class that will allow us to configure receptions. Let's take a look to the configuration:

As you can see, we have declared the port that will listen and through which the images sent from the PACS will be received. We have also configured both the local AET (IRIS) and the PACS that will send us the DICOM (ORTHANC), remember that these fields are mandatory and are the ones that will be used to check the validity of sending and receiving DICOM messages. Do not forget that both AETs must be configured and related from the DICOM Settings menu:

As you can see, we have configured both the sending of messages from IRIS to ORTHANC (the case of the previous article) and from ORTHANC to IRIS (the case at hand). Confirm that you have configured for both association contexts the presentation contexts with the types of DICOM images that you send and receive in both systems.

Finally, indicate that we have defined the parameter with the destination component to which we will send the DICOM image sent by the PACS, in this case we have named it with the same name as the class to which it belongs: Demo.DICOM.Process.StorageLocal

Let's take a closer look at the code of the main method of this class:

Method OnMessage(pSourceConfigName As %String, pInput As %Library.Persistent) As %Status
{
	#dim tSC As %Status = $$$OK
	#dim e As %Exception.AbstractException
	#dim tMsgType,tMsgId As %String
	#dim tOutput As EnsLib.DICOM.Document
	
	Try {
		
		#; We should only ever see DICOM Documents here
		$$$ASSERT(pInput.%Extends("EnsLib.DICOM.Document"))
		
		#; We only ever get DICOM Documents from the Service
		$$$ASSERT(pSourceConfigName=..ServiceDuplexName)
		 	
 		#; Get the CommandField, it contains the type of request, it should ALWAYS be present
		Set tMsgType=$$$MsgTyp2Str(pInput.GetValueAt("CommandSet.CommandField",,.tSC))
		If $$$ISERR(tSC) Quit
		#; We are only handling Storage Requests
		$$$ASSERT(tMsgType="C-STORE-RQ")

		#; Record the originating message id
		Set tMsgId=pInput.GetValueAt("CommandSet.MessageID",,.tSC)
		If $$$ISERR(tSC) $$$LOGSTATUS(tSC) Quit
		#; We can forward the document to the operation
		Set tSC=..SendRequestSync("Demo.DICOM.Operation.File",pInput)
		If $$$ISERR(tSC) Quit
		#; We need to send a reply to the service in all cases, so create an appropriate response
		Set tSC=..CreateStorageResponse(pInput,.tOutput)
		If $$$ISERR(tSC) Quit
		#; Send the reply back to the service ( don't want a response )
		Set tSC=..SendRequestAsync(..ServiceDuplexName,tOutput,0)
		If $$$ISERR(tSC) Quit
		#; Stop the private session to ensure each message gets its own session				
		Set tSC=..StopPrivateSession(..ServiceDuplexName)
		If $$$ISERR(tSC) Quit
	} catch (e) {
		Set tSC=e.AsStatus()
	}
	
	Quit tSC
}

First we make sure that the message received is of the DICOM type, then we confirm that it has been received from the Business Service defined for it and finally we check that the requested operation corresponds to C-STORE-RQ.

Next, our class will create the response DICOM message that will be sent to the PACS with the received message identifier and finally will be sent to the Business Operation in charge of storing the DICOM message in a file. We are also going to see the code of the main method of that Business Operation Demo.DICOM.Operation.File:

Method OnMessage(pRequest As %Library.Persistent, Output pResponse As %Library.Persistent) As %Status
{
	#dim tSC As %Status = $$$OK
	#dim e As %Exception.AbstractException
	#dim tFile As EnsLib.DICOM.File
	#dim tFileName As %String
	try {
		
		#; We should only ever see DICOM Documents here
		$$$ASSERT(pRequest.%Extends("EnsLib.DICOM.Document"))
		
		#; Create a DICOM File from the DICOM document
		Set tSC=##class(EnsLib.DICOM.File).CreateFromDocument(pRequest,.tFile)
		If $$$ISERR(tSC) Quit
		#; Create a unique filename
		Set tFileName=..NewFilename(..FileStorageDirectory)
		
		#; Create a new file with a unique name and the dcm extension in the target directory
		Set tSC=tFile.Save(tFileName)
		
	} catch(e) {
		Set tSC=e.AsStatus()
	}
	Quit tSC
}

Simple, isn't it? We are receiving our message of type EnsLib.DICOM.Document and we are generating a file with the message data.

As you can see, it is not very complex and the result is a very simple production:

 

OK, with our production configured and running we can launch a test sending an image from the UI of our PACS, in this case ORTHANC.

 

We access one of the studies that we previously stored in the previous article and click on the "Send to DICOM modality" option. In our case we only have one DICOM modality configured, the IRIS one.

By clicking on our modality we will be sending the entire study via TCP/IP to our IRIS for Health. ORTHANC will provide us with a screen with the status of the job that has been launched. We can check how its status is "Success". Therefore we should see the reception of the message in our production.


Let's see the messages that have arrived at our Business Service EnsLib.DICOM.Service.TCP:

And there is it! We have received a message, let's enter the complete trace of the message and confirm that it has gone through all the components successfully:

 

And here we have it! Our message has been received, a new DICOM message has been generated that has been forwarded as a response to our PACS and finally we have generated our DICOM type file where we have saved our image.

Well then, we would already have our production running for the reception of DICOM messages via TCP/IP. In this case we have configured it to create a file, but it could be modified to redirect to another mode via TCP/IP and even to transform it into a base64 to attach it to an HL7 message (I don't recommend it because of the size can reach these types of messages).

If you have any questions or suggestions, you already know that you can write them in the comments section and we will be happy to answer them.

Discussion (2)2
Log in or sign up to continue