Tuesday, December 18, 2012

DICOM Server and DICOM Toolkit new Release 2.0.2.8

The last couple of weeks were very busy with many installations of the DICOM Server all over the world. It turned out to be a product that many people were waiting for and we've been busy with installations and support work. Naturally, many issues were found and fixed. These fixes and improvements were gathered into the last release that is now available online. It was great fun to see that people liked the idea of the server and modified and customized the database mappings to meat their own requirements. For me this was the best indication that the product concept is really working.

Release 2.0.2.8

A new release is ready on the DICOM downloads page. This release addresses couple of bug fixes and improvements to the DICOM Server and DICOM Toolkit. Many of these changes were initiated by customers requests and I would like to thank you for the feedback and bug reports.

API Changes

The most important thing to notice in this release is that some API calls were changed and it is not 100% backwards compatible with earlier releases. These changes are in the C-MOVE callback and in the get property of date and time elements. For more details please read the release notes in the download package.

DICOM Server Q/R Automatic Tag Mapping

The most interesting work in this release was done on the server Q/R functionality and database API. The new release is much easier to enhance and customize to your needs with the fully dynamic query response functionality.
This is actually the feature that I like most in the DICOM Server and I'm going to describe it and explain how it works in this post.

A detailed article about Q/R can be found here. The relevant part for integrating your database with the DICOM Server is how the C-FIND Request Identifier is processed and translated into SQL Query, and how the C-FIND Response Identifiers are constructed.

This is a typical Patient level query sent from a Workstation:

(0008,0052) CS [PATIENT]                                    #  8       1  QueryRetrieveLevel
(0010,0010) PN [J*]                                         #  2       1  PatientName
(0010,0020) LO []                                           #  0       0  PatientID
(0010,0030) DA [20120101-]                                  #  10      1  PatientBirthDate
(0010,0032) TM []                                           #  0       0  PatientBirthTime
(0010,0040) CS []                                           #  0       0  PatientSex
(0010,1000) LO []                                           #  0       0  OtherPatientID
(0010,1001) PN []                                           #  0       0  OtherPatientNames
(0010,2160) SH []                                           #  0       0  EthnicGroup
(0010,4000) LT []                                           #  0       0  PatientComments
(0020,1200) IS []                                           #  0       0  NumberOfPatientRelatedStudies
(0020,1202) IS []                                           #  0       0  NumberOfPatientRelatedSeries
(0020,1204) IS []                                           #  0       0  NumberOfPatientRelatedImages

When processed by our DICOM server, this query is translated to the following SQL Command:

SELECT     PatientName, PatientID, PatientBirthDate, PatientSex
FROM         CFIND_PATIENT_VIEW
WHERE     (PatientName LIKE 'J%') AND (PatientBirthDate >= CONVERT(datetime, '20120101'))

As you can notice only four out of the requested DICOM elements are in the SQL Query because out of the requested attributes only these four could be mapped to the fields of CFIND_PATIENT_VIEW in my database. 

The view name is constructed from the query level and the SOP Class UID of the query model. When a STUDY level query is received, the view name is CFIND_STUDY_VIEW and so on.. If from some reason you would like the server to have CLINIC query level, you can map this view just as well though of course it is not part of the standard.

After deciding on the view, the server tries to map every DICOM field to a column in the view simply by matching the names from the DICOM tags dictionary to the names of the columns.in the new release the matching is not case sensitive as in the previous versions where for example the modality column didn't map to the Modality tag which caused a lot of support calls. If for example we'll modify the view to have rows counters for study, series and images, then these fields will be added automatically. you can test this yourself by changing the view with the following command and see that you will get these attributes too:

ALTER VIEW [dbo].[CFIND_PATIENT_VIEW]
AS
SELECT     
  patient_id AS PatientID, 
  patient_name AS PatientName, 
  patient_sex AS PatientSex, 
  patient_birth_date AS PatientBirthDate, 
  CAST(COUNT(DISTINCT study_instance_uid) AS varchar(9)) AS NumberOfPatientRelatedStudies,
  CAST(COUNT(DISTINCT series_instance_uid) AS varchar(9)) AS NumberOfPatientRelatedSeries,
  CAST(COUNT(DISTINCT sop_instance_uid) AS varchar(9)) AS NumberOfPatientRelatedInstances
FROM         dbo.DICOM_FILES
GROUP BY patient_id, patient_name, patient_sex, patient_birth_date

The cast is required because IS VR is a string type and the server expects to get a string from the database. Now the query at patient level can return the three sub level counters. No other change is required not even restarting the service. The server will immidatly pick up the changes and map the database view columns to the query response DICOM tags. 

On the next post, I'm going to continue the review of the database mapping feature and explain how to map sequence tag for Q/R sequence matching that is used in Modality Worklist Query.

No comments:

Post a Comment