In chapter 3 we’ve learned about DICOM elements. Every element is one piece of typed data with a pre defined, well specified meaning. There are thousands of DICOM elements (See chapter 6 of the standard) from the very basic attributes of patient name and birth date to the most esoteric uses of 3D surface vortices. In this chapter we’re going to collect elements into image object that is called Secondary Capture Image.
The guys at DICOM did a lot of very good work and created well defined classes for a very detailed Data Model. This is why I always advise to dig in the DICOM standard before designing your imaging device software because there’s a very good chance that the DICOM technical committees already did the work for you and you can save a lot of expansive design time this way.
In a way DICOM objects definitions are similar to object oriented programming. I prefer though the analog to interfaces specifications. The motivation to adhere to a standard is to enable interoperability. By detailing information object definitions (IOD’s) DICOM enables us to exchange virtual objects between applications without knowing in advance anything about the application we are going to interface with.
In this chapter I'm going to complete chapter’s 3 examples by adding elements to the object until it’s a valid Secondary Capture Image according to the DICOM standard. Secondary Capture Image is the simplest DICOM image object. Secondary Captures is not related to any specific device. It has the very basic set of elements that a DICOM application needs in order to display and archive a DICOM image properly.
The DICOM Data
The specification of DICOM objects are documented in chapter 3 of the DICOM standard that defines the DICOM data model. In its most simplified form the DICOM Data Model looks like this.
A simplified view of the DICOM Data Model
The data model defines Information Entities (IE’s); Patient, Study, Series and Image. There are more IE’s like Visit, Equipment, Clinical Trial, Procedure and many others and they are all defined in chapter 3 which is the longest chapter of the standard. The DICOM Data Model that is made of IE's is normalized. It is a perfect relational database definition. The classes of the DICOM Objects however are composites made of modules from different entities. The integration is achieved by applications that exchange composite objects between one another. Each application is responsible for it's own internal normalized database that is private to itself and should not interest any other application and is out of the standard's scope. The way you build your DICOM application internals is completely your business. The only thing that matters is your interfaces. Your application should talk proper DICOM. By the way, the DICOM network protocol that we’ll get to in later chapters also makes a distinction between Normalized and Composite operations and there’s N protocol and C protocol with different commands for each one.
The classes of the DICOM static data model are called SOP Classes and are defined by IOD’s – Information Object Definition. IOD’s are specified in Appendix A of chapter 3 of the standard. An IOD is a collection of Modules and a Module is a collection of elements from one information entity that together represent something. The modules are also defined in chapter 3 of the DICOM standard in appendix C. Two object oriented concepts, composition and reuse, that are used by DICOM is the Modules that are parts shared between different IOD’s.
All DICOM Objects must include the SOP Common Module and modules from the four main IE’s: Patient, Study, Series and Image (Image and Instance are the same in DICOM. Once there were only images but then objects that are not images has been defined and the name thus changed from Image to Instance in order to represent an instance of a SOP class). All DICOM Images, that is DICOM Instances that Are Images, must include the Image Module. Because Every DICOM Object must be part of a Series, all DICOM Objects must include the General Series Module and because all series must be part of a Study, every DICOM Object must include the General Study Module and because every study is made on some patient, all DICOM objects must have a Patient Module. You probably wonder what SOP means? That's an acronym for "Service Object Pair" and please take my word for it, that for now this is all we need to say about that. Maybe when we talk about DICOM Services or understanding DICOM Conformance Statements I'll try to explain where this name comes from, but I'm not sure that it makes much difference. In a word, SOP is a pair of a DICOM Sevice and and DICOM Object like Secondary Capture Object and Storage Service.
Secondary Capture Image
With that understanding at hand, let’s look at the SC Image IOD Modules from section A.8.1.3 of the standard. It looks like this:
Clinical Trial Subject
Clinical Trial Study
Clinical Trial Series
Taking out all the lines marked with a U that mark these modules as User optional and leaving only the M lines that stand for Mandatory modules and we are left with eight modules that one of them is actually empty as you will soon find out.
Note also that in this table there are only two modules that are specific to SC and all the other modules are general and common modules that are shared by many IOD’s. It's very common in DICOM that the mandatory elements are very few and there are a lot of optional elements. This is not unique to the DICOM standard and is common to many standards and sometime leads to uncertainties and ambiguities or gaps as we sometime call them. These gaps led IHE to publish technical frameworks that further specify the use of the standard and narrow the options. The IHE initiative is a great success and participating in IHE connect-a-thon is an outstanding opportunity to test systems in a very realistic integration environment.
During the design of your application, when you need to add some data to an object and don’t find a proper place for it, remember these optional modules that we’ve omitted here and look for a place to put your data in them before defining private elements, modules and objects. DICOM let you define new elements that are called private elements and we’ll look at that later on but as already said more than once, there’s a very good chance that these guys have already did the work for you and defined a solution to your problem and went through the process of validating it and it is probably documented very well in the standard. After all, the DICOM standard is more than 3,000 pages long.
To finish our digging in the DICOM standard, we now need to replace every line in the modules table with the module's definition from appendix C of chapter 3 of the DICOM standard. If you look at the standard you will see that every module is rather large and includes many elements but luckily, like the optional modules, many of the elements are optional too. In the modules tables elements are marked with a ‘Type’ column that can be 1 for Mandatory with actual value (not zero length), 2 for Mandatory that can be null (zero length) or 3 for optional. 1 and 2 can also have a ‘C’ for conditional so 1C is mandatory if some condition, that is detailed in the module table, is met and the same for 2C.
So we are now going to copy the modules but only the 1 and 2 elements dumping all the 3’s and also 1C and 2C’s that their condition is obviously not met for our example. Remember that we are talking interoperability so striving to the simplest object that as many systems as possible can understand is our goal.
Next to every element I’m going to add the C# code to add it into the object and at the end we’re going to have all the code at hand.
One last thing, before we dive into the code, I’d like to say a word about Unique Identifiers. DICOM makes extensive use of Unique Identifiers. Almost every entity in the DICOM Data Model has a unique identifier. In DICOM every SOP Class have its UID. All pre-define UID’s including the SOP Class UID’s are documented in chapter 6 of the DICOM standard. A DICOM Object is an Instance of such class and is called SOP Instance and it also has a UID called SOP Instance UID. DICOM defines a mechanism in order to make sure UID’s are globally Unique. Every DICOM application should acquire a ‘root’ UID that is used as a prefix to the UID’s it creates. Every entity in the DICOM Data Model also has a UID with the exception of the patient. Patients are identified using the combination of their name and ID. Studies, Series, all have UID’s. DICOM Archives (PACS) should use the UID’s to index their databases so when other applications make searches (Queries) they can refer to objects using the UID’s and the archive can respond to the searches quickly.
As I said earlier, every DICOM Image Object has patient, study, series, and image modules. In our example we’ll generate new UID’s for Series Instance UID and SOP Instance UID (that is the Image UID). In "proper" DICOM integration the Study Instance UID is provided by the department IT system (RIS/PACS) through a DICOM service called Modality Worklist but devices can default to creating the Study Instance UID if it’s not provided from an external system. The Series Instance UID and SOP Instance UID are always generated by the Imaging device. The definition of a DICOM series is a set of DICOM Instances that were generated together by the same equipment at the same operation. You can read the exact definition in section A.1.2.3 of chapter 3 of the standard.
Creating a Secondary Capture
// create the object
DCXOBJ o = newDCXOBJ();
Table C.7-1 PATIENT MODULE ATTRIBUTES
// Create element
DCXELM e = newDCXELM();
Patient's full name.
// Patient name
// But we set it to
Primary hospital identification number or
code for the patient.
// Patient ID - type 2 can be
Patient's Birth Date
Birth date of the patient.
Sex of the named patient.
M = male
F = female
O = other
GENERAL STUDY MODULE ATTRIBUTES
Study Instance UID
Unique identifier for the Study.
// Let's assume we got a Study
// UID from the department IT
// and that it's 184.108.40.206.5.6.7
e.Value = "220.127.116.11.5.6.7";
Date the Study started.
// Let's say the study was
created now e.Init((int)DICOM_TAGS_ENUM.StudyDate);
Laterality of (paired) body part examined. Required
if the body part examined is a paired structure and Image Laterality (0020,0062) or Frame Laterality (0020,9072) arenot sent. Enumerated Values:
R = right
L = left
Note: Some IODs support Image Laterality
(0020,0062) at the Image level or Frame
Laterality(0020,9072) at the
Frame level in the Frame Anatomy functional group macro, which can provide a
more comprehensive mechanism for specifying the laterality of the body
part(s) being examined.
SC EQUIPMENT MODULE ATTRIBUTES
Describes the kind of image conversion.
Defined Terms :
DV = Digitized Video
DI = Digital Interface
DF = Digitized Film
WSD = Workstation
SD = Scanned Document
SI = Scanned Image
DRW = Drawing
SYN = Synthetic Image
e.Value = "DRW";
Source equipment for the image. This type
definition shall override the definition in the General Series Module.
See C.18.104.22.168.1 for Defined Terms.
// See comment above about Modality
here I left in a type 3 element named Modality. Read the description and see
why. What it says here is that a SC image doesn’t have to have a Modality
GENERAL IMAGE MODULE ATTRIBUTES
A number that identifies this image.
Note: This Attribute was named Image Number
in earlier versions of this Standard.
Patient direction of the rows and columns of the
image. Required if image does not require Image Orientation (Patient) (0020,0037) and Image Position (Patient) (0020,0032). May be present otherwise. See C.22.214.171.124.1
for further explanation.
Note: IOD’s may have attributes other than
Patient Orientation, Image Orientation, or Image Position (Patient) to
describe orientation in which case this attribute will be zero length.
// Let's assume the condition
// for all the 2C's bellow
// is not met
The date the image pixel data creation started.
Required if image is part of a series in which the images are temporally
Note: This Attribute was formerly known as
The time the image pixel data creation started.
Required if image is part of a series in which the images are temporally
ff\ff\ff\ff\ff\ff\ff\ff\ff\ff\ff\ff\ff\ff\ff\ff\ff\ff\ff\ff\ff\ff... # 7500, 1
Couple of notes about this dump (highlighted).
First you can see the UID of this instance. Whenever you run this code again, a new UID will be generated. The same goes for Series Instance UID.
See the (7fe0,0010) element? This is the pixel data. The pixels from the bitmap image we’ve converted. It is 7500 bytes long because the image I converted is 50x50 and there's 3 bytes per pixel (Red, Green and Blue).
Look at Study Date (0008,0020) and Study Time (0008,0030). The DA (Date) VR (Value Representation) is defined as formatted date string YYYYMMDD and the TM (Time) VR is a time formatted string with format HHMMSS.TTT. You can see that I ran this example four minutes before midnight on December 1st 2011.
Here’s a short quiz:
Look at the length Photometric Interpretation (0028,0004). The value is “RGB” but the value length is 4 bytes. Why?
This was quite long and complicated chapter covring the DICOM Data Model, Information Entities, Modules, Information Objects Definitions (IOD's), SOP Classes and SOP Instances, Unqiue Identifiers and element types. Most important, we've walked through the process of reading chapter 3 of the standard and translating it to a software that creates the DICOM Object according to the standard specifications. I hope it wasn't too complicated. As always, comments and questions are most welcome.