Saturday, May 18, 2013
Google Custom Search

Our Community

Membership Membership:
Latest New User Latest: boasquevisque
New Today New Today: 0
New Yesterday New Yesterday: 12
User Count Overall: 28630

People Online People Online:
Visitors Visitors: 6
Members Members: 0
Total Total: 6

Online Now Online Now:

ClearCanvas Community Forums

We've moved our Developer Forums!
To better assist our open source community, we have moved our repository and developer forums to GitHub. You can access the new developer forums on our ClearCanvas GitHub issues board.

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

--
2011-12-04 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



art
New Member
New Member
Posts:7

--
2011-12-10 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

jasper.yeh
Senior Member
Senior Member
Posts:525
Avatar

--
2011-12-12 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


// Jasper
art
New Member
New Member
Posts:7

--
2011-12-16 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?



stewart
Senior Member
Senior Member
Posts:2336

--
2011-12-16 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


Live and real-time support available for Personal and Team Edition customers
art
New Member
New Member
Posts:7

--
2011-12-27 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


stewart
Senior Member
Senior Member
Posts:2336

--
2012-01-03 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.


Live and real-time support available for Personal and Team Edition customers
art
New Member
New Member
Posts:7

--
2012-01-04 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


art
New Member
New Member
Posts:7

--
2012-01-07 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?
 


art
New Member
New Member
Posts:7

--
2012-01-13 02:53 PM

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



You are not authorized to post a reply.

Active Forums 4.1
Copyright 2013 ClearCanvas Inc. All Rights Reserved