Do you have a question?

First Name:
Surname:
Email:
Phone:
Message:
Get Audio Code

Query Retrieve with Visual Basic .NET
Last Post 13 Jan 2012 02:53 PM by Beat A. 9 Replies.
Printer Friendly
Sort:
PrevPrev NextNext
You are not authorized to post a reply.
Author Messages
artUser is Offline
New Member
New Member
Posts:2

--
04 Dec 2011 02:03 PM  

 Hi,

Starting with ClearCanvas I would like to create a minimalistic Query Retrieve Service for our PACS. Has anybody written a VB.NET Query Retrieve Service which I could use as a base?

Thanks in advance

Beat



Beat AUser is Offline
New Member
New Member
Posts:7

--
10 Dec 2011 11:02 AM  

 In the meantime I found online-tools (http://converter.telerik.com/) to transform the C# code to VB.NET and they do a very good job. Then I tried to work with the sample-code. See the code in the attachment.

Unfortunately I did not yet find code to do a query on another server.


Attachment: CC_with_VB2010.zip

JasperUser is Offline
Advanced Member
Advanced Member
Posts:525

--
12 Dec 2011 11:07 AM  
Hi Beat,

If you're using the ClearCanvas.Dicom assembly as a reference, you should be able to use the ClearCanvas.Dicom.Network.Scu.StudyRootFindScu class to find a study, then use the ClearCanvas.Dicom.Network.Scu.StudyRootMoveScu class to move the study locally.

My VB is very rusty, but I believe it should look something like
Using findscu as New StudyRootFindScu()
Dim query as New DicomAttributeCollection()
query[DicomTags.QueryRetrieveLevel].SetStringValue("STUDY") 'must be STUDY
query[DicomTags.PatientId].SetStringValue("PATIENTID") 'change this
query[DicomTags.PatientsName].SetStringValue("PATIENTSNAME") 'change this
query[DicomTags.StudyInstanceUid].SetStringValue(String.Empty) 'must be blank
query[DicomTags.StudyId].SetStringValue("STUDYID") 'change this
query[DicomTags.StudyDescription].SetStringValue("DESCRIPTION") 'change this
query[DicomTags.AccessionNumber].SetStringValue("A#") 'change this

Dim results = findscu.Find("LOCALAE", "REMOTEAE", "REMOTEHOST", REMOTEPORT, query) 'replace with the local client's AE and remote server's details
rem figure out which result you want to retrieve, and get its study instance UID
End Using

Using moveScu as new StudyRootMoveScu("LOCALAE", "REMOTEAE", "REMOTEHOST", REMOTEPORT, "LOCALAE") 'replace with the local client's AE and remote server's details
moveScu.AddStudyInstanceUid("STUDYINSTANCEUID") 'replace with study instance UID from result you want to retrieve
moveScu.Move()
End Using


Beat AUser is Offline
New Member
New Member
Posts:7

--
16 Dec 2011 10:03 AM  
Thanks Jasper for the code snippet. What I do not yet understand: how do I receive requests within an application built with the ClearCanvas-SDK? If another client sends a search there must be service ready to answer the request. I saw the code to receive and save images to disk but I have not seen a code snippet that shows me how to receive and handle search-requests and how to give back the search results. Where can I find such code within the ClearCanvas framework?



stewartUser is Offline
Veteran Member
Veteran Member
Posts:2359

--
16 Dec 2011 04:33 PM  
There's nothing in the framework/SDK, per se, but you can "borrow" the code from the Workstation's DICOM Server, and just make changes where you need to - it might even work pretty much as-is, if you're ok using the viewer's current storage mechanism (SQL CE + Study XML); the Workstation's DICOM Server is pretty light, and is ideal for simple storage applications, really. The only part you might have trouble with is the stuff that publishes activity through the Local Data Store service, if you don't want to keep it. That stuff might also strip out pretty easily.

The class that responds to queries, in the Workstation anyway, is called FindScpExtension.

If you're looking to build your own SCP from scratch, you can start with DicomScp; this is the starting point for building your own DICOM service(s). This class automatically discovers extensions of DicomScpExtensionPoint, each of which generally corresponds to one DICOM service (C-FIND, C-MOVE, C-STORE, etc). Search for usages of this in the Workstation code to figure out how it works.

Hope this helps,
Stewart


Beat AUser is Offline
New Member
New Member
Posts:7

--
27 Dec 2011 05:47 AM  
Hi Stewart
Thanks for your help which gave me a good starting point to dig in the huge amount of code.
I am still confused about the behaviour of the little application I uploaded some days ago. As far as I can see, the SCP and SCU works fine but I can not trap any Find- requests I would expect an event to fire if I make a search in KPACS or eFilm but this is not the case. I have implemented all event handlers like:
- OnReceiveAssociateRequest
- OnReceiveRequestMessage
- OnReceiveResponseMessage
- OnReceiveReleaseRequest
- OnReceiveAbort
- OnNetworkError
- OnDimseTimeout
All this events are defined in "IDicomServerHandler".
Do I have missed something an if yes, how to implement an additional event?

Kind regards

Beat


stewartUser is Offline
Veteran Member
Veteran Member
Posts:2359

--
03 Jan 2012 11:21 AM  
You need to add SopClass.StudyRootQueryRetrieveInformationModelFind with ELE and ILE Transfer Syntaxes to the list of presentation contexts. Otherwise, the association is rejected at a lower level because your server doesn't support C-FIND.


Beat AUser is Offline
New Member
New Member
Posts:7

--
04 Jan 2012 02:16 PM  
Hi Stewart,
thanks for support. Only three lines more to trap C-FIND REQUESTs.
Of course I have to solve many other problems but I shall stay on. Next is to intergrate the code from the class "FindScpExtension".

Kind regards

Beat


Beat AUser is Offline
New Member
New Member
Posts:7

--
07 Jan 2012 03:04 PM  

Hi Stewart,

Now that I am able to catch the "C-FIND REQUEST" I made a little test within my sample application but there occured errors.
 
Code snippet within sample application (VB.NET 2010):
 
Private Sub OnReceiveRequestMessage(ByVal server As DicomServer, ByVal association As ServerAssociationParameters, ByVal presentationID As Byte, ByVal message As DicomMessage) Implements IDicomServerHandler.OnReceiveRequestMessage

Select Case message.CommandField
Case DicomCommandField.CEchoRequest
......
Case DicomCommandField.CFindRequest
server.SendCFindResponse(presentationID, message.MessageId, message, DicomStatuses.Success)
Dim level As [String] = message.DataSet(DicomTags.QueryRetrieveLevel).GetString(0, "").Trim()

If message.AffectedSopClassUid.Equals(SopClass.StudyRootQueryRetrieveInformationModelFindUid) Then
Dim response As New DicomMessage()
'Faked answer. Will be replaced with datas out of a database
response.DataSet(DicomTags.StudyDate).SetStringValue("20120107")
response.DataSet(DicomTags.StudyTime).SetStringValue("16:00:00")
response.DataSet(DicomTags.Modality).SetStringValue("MR")
response.DataSet(DicomTags.StudyDescription).SetStringValue("Test")
response.DataSet(DicomTags.StudyId).SetStringValue("1000000001")
response.DataSet(DicomTags.StudyInstanceUid).SetStringValue("1.2.840.113680.1.103.61237.1079337801.832066")
response.DataSet(DicomTags.AccessionNumber).SetStringValue("1234567")
response.DataSet(DicomTags.PatientId).SetStringValue("121212")
response.DataSet(DicomTags.PatientsName).SetStringValue("Doe^Joe")
response.DataSet(DicomTags.PatientsBirthDate).SetStringValue("19600101")
response.DataSet(DicomTags.PatientsSex).SetStringValue("M")
response.DataSet(DicomTags.ReferringPhysiciansName).SetStringValue("Mueller")

message.DataSet(DicomTags.RetrieveAeTitle).SetStringValue(My.Settings.SCPAETitle.ToString)
message.DataSet(DicomTags.InstanceAvailability).SetStringValue("ONLINE")

response.DataSet(DicomTags.QueryRetrieveLevel).SetStringValue(level)
server.SendCFindResponse(presentationID, message.MessageId, response, DicomStatuses.Pending)

Dim finalResponse As New DicomMessage()
server.SendCFindResponse(presentationID, message.MessageId, finalResponse, DicomStatuses.Success)
Endif
End Select
End Sub
 
-----------------
Log within sample application:
 
(15) 07.01.2012 20:47:13 (Info) LogQueryReceived. CallingAE: KPServer, RemoteHostName: T500-ART, Success: ClearCanvas.ImageViewer.Services.Auditing.EventResult, AffectedSOPClassUID: 1.2.840.10008.5.1.4.1.2.2.1, MessageID ClearCanvas.Dicom.DicomAttributeCollection
(15) 07.01.2012 20:47:13 (Error) Unexpected network error over association from KPServer.
 
-----------------
Log within KPacs:
 
*******************************************************
07.01.2012 20:47:12 ThreadID[0] : C-Find request on STUDY level with StorageSCP       initiated.
*******************************************************
[DICOM SCU]        >> : Connected to: localhost:105
[DICOM SCU]        >> : Item Type: 2
[DICOM SCU]        >> : Association Accept::ReadDynamic
[DICOM SCU]        >> : Presentation Context Accept, Transfer Syntax: 1.2.840.10008.1.2
[0]        >> : c-Find association with StorageSCP       opened
[0]        >> : c-Find request processed
[0]        >> : STATUS: $0000
*******************************************************
07.01.2012 20:47:13 ThreadID[0] : Closed.
Task processed with errors
*******************************************************
What did I wrong?
 


Beat AUser is Offline
New Member
New Member
Posts:7

--
13 Jan 2012 02:53 PM  

 Problem solved. I had to delete the first line...



You are not authorized to post a reply.

Active Forums 4.1