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
}
ObjectScriptObjectScript
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
}
ObjectScriptObjectScript
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.
Very good materials ; thanks @Luis Angel Pérez Ramos
You are welcome Sylvain!