DICOM Basics using Java - Multi-modality Examples

Introduction

This is part of my series of articles on the DICOM standard. In this tutorial, we'll explore the modality-specific attributes for different imaging types. Understanding these attributes is essential for proper DICOM handling across CT, MR, ultrasound, X-ray, and nuclear medicine systems.

Each modality has unique attributes that capture acquisition parameters, technical settings, and modality-specific information.

Prerequisites

Before you begin, ensure you have the following:

  • Java JDK installed (Java 8 or later)
  • PixelMed Java DICOM Toolkit
  • You can find all the code demonstrated in this tutorial on GitHub here

“The eye sees only what the mind is prepared to comprehend.” ~ Robertson Davies

The Theory Behind Modality-Specific Attributes

DICOM's modality-specific modules address a fundamental challenge: each imaging physics produces unique technical parameters that are clinically essential but incompatible across modalities.

Why Modality Modules Exist

Consider what makes an image interpretable:

  • CT: Hounsfield Units, reconstruction kernel, radiation dose
  • MR: TR, TE, flip angle, magnetic field strength, sequence type
  • US: Transducer frequency, mechanical index, thermal index
  • NM: Radiopharmaceutical, injected dose, decay correction

A radiologist cannot interpret an MRI without knowing the sequence type (T1, T2, FLAIR). These parameters have no meaning for CT. DICOM's modality modules provide the acquisition context necessary for clinical interpretation.

The IOD Composition Model

DICOM Information Object Definitions (IODs) are composed of modules like building blocks:

CT Image IOD:
  Patient Module (common)
  + General Study Module (common)
  + General Series Module (common)
  + General Equipment Module (common)
  + CT Image Module (CT-specific)
  + Image Pixel Module (common)
  + ...

Common modules ensure basic interoperability (any viewer can identify the patient), while modality modules provide domain-specific richness.

Understanding Rescale and Calibration

A critical concept is how stored pixel values map to physical quantities:

  • CT: Stored values → Rescale Slope/Intercept → Hounsfield Units (HU = slope × pixel + intercept)
  • PET: Stored values → Activity concentration → SUV (requires patient weight and injected dose)
  • MR: Stored values are typically arbitrary (no physical unit calibration in standard MR)

Understanding these calibration chains is essential for quantitative imaging applications.

Enhanced vs. Classic IODs

DICOM has evolved from "Classic" single-frame IODs to "Enhanced" multi-frame IODs:

  • Classic: One DICOM file per image, attributes at instance level
  • Enhanced: All frames in one file, shared vs. per-frame functional groups

Enhanced IODs eliminate redundancy (patient name stored once, not per-slice) and better represent acquisition relationships (all slices from one spiral CT acquisition belong together).

Common Modality Codes

CodeModalitySOP Class Example
CTComputed Tomography1.2.840.10008.5.1.4.1.1.2
MRMagnetic Resonance1.2.840.10008.5.1.4.1.1.4
USUltrasound1.2.840.10008.5.1.4.1.1.6.1
XAX-Ray Angiography1.2.840.10008.5.1.4.1.1.12.1
DXDigital Radiography1.2.840.10008.5.1.4.1.1.1.1
MGMammography1.2.840.10008.5.1.4.1.1.1.2
NMNuclear Medicine1.2.840.10008.5.1.4.1.1.20
PTPET1.2.840.10008.5.1.4.1.1.128

CT (Computed Tomography) Attributes

System.out.println("=== CT (Computed Tomography) ===");

System.out.println("CT Image Module:");
System.out.println("  (0018,0060) KVP - X-ray tube voltage (e.g., 120 kV)");
System.out.println("  (0018,1151) X-Ray Tube Current - mA (e.g., 250)");
System.out.println("  (0018,1150) Exposure Time - ms (e.g., 500)");
System.out.println("  (0018,1152) Exposure - mAs (e.g., 125)");
System.out.println("  (0018,9345) CTDIvol - dose index in mGy");
System.out.println("  (0018,0050) Slice Thickness - mm (e.g., 1.25)");
System.out.println("  (0018,0088) Spacing Between Slices - mm");

System.out.println("CT Reconstruction:");
System.out.println("  (0018,1100) Reconstruction Diameter - mm (FOV)");
System.out.println("  (0018,1210) Convolution Kernel - e.g., STANDARD, BONE");
System.out.println("  (0018,5100) Patient Position - HFS, HFP, FFS, FFP");

System.out.println("Hounsfield Units:");
System.out.println("  (0028,1052) Rescale Intercept - typically -1024");
System.out.println("  (0028,1053) Rescale Slope - typically 1");
System.out.println("  HU = Rescale Slope * Pixel Value + Rescale Intercept");
System.out.println("  Water = 0 HU, Air = -1000 HU, Bone = +400 to +1000 HU");

MR (Magnetic Resonance) Attributes

System.out.println("=== MR (Magnetic Resonance) ===");

System.out.println("MR Image Module:");
System.out.println("  (0018,0020) Scanning Sequence - SE, IR, GR, EP, RM");
System.out.println("  (0018,0021) Sequence Variant - SK, MTC, SS, SP, MP");
System.out.println("  (0018,0023) MR Acquisition Type - 2D, 3D");
System.out.println("  (0018,0080) Repetition Time (TR) - ms");
System.out.println("  (0018,0081) Echo Time (TE) - ms");
System.out.println("  (0018,0082) Inversion Time (TI) - ms");
System.out.println("  (0018,0083) Number of Averages (NEX/NSA)");
System.out.println("  (0018,0087) Magnetic Field Strength - Tesla");
System.out.println("  (0018,0091) Echo Train Length");
System.out.println("  (0018,1314) Flip Angle - degrees");

System.out.println("Common Sequence Types:");
System.out.println("  T1-weighted: Short TR (~500ms), Short TE (~10-20ms)");
System.out.println("  T2-weighted: Long TR (~2000-4000ms), Long TE (~80-120ms)");
System.out.println("  FLAIR: Long TR, Long TE, TI ~2500ms");
System.out.println("  DWI: Echo-planar, b-value in (0018,9087)");

US (Ultrasound) Attributes

System.out.println("=== US (Ultrasound) ===");

System.out.println("US Image Module:");
System.out.println("  (0018,6011) Sequence of Ultrasound Regions");
System.out.println("  (0018,602C) Physical Delta X - mm per pixel");
System.out.println("  (0018,602E) Physical Delta Y - mm per pixel");
System.out.println("  (0018,6030) Transducer Type - SECTOR, LINEAR, CURVED");
System.out.println("  (0008,2144) Recommended Display Frame Rate");

System.out.println("US Region Calibration:");
System.out.println("  (0018,6018) Region Spatial Format - 2D, M-MODE");
System.out.println("  (0018,601A) Region Data Type - COLOR_FLOW, TISSUE");
System.out.println("  (0018,6024) Physical Units X Direction");
System.out.println("  (0018,6026) Physical Units Y Direction");

System.out.println("Multi-frame (cine loops):");
System.out.println("  (0028,0008) Number of Frames");
System.out.println("  (0018,1063) Frame Time - ms between frames");

XA (X-Ray Angiography) Attributes

System.out.println("=== XA (X-Ray Angiography) ===");

System.out.println("XA Image Module:");
System.out.println("  (0018,1147) Field of View Shape - RECTANGLE, ROUND");
System.out.println("  (0018,1149) Field of View Dimension(s) - mm");
System.out.println("  (0018,1510) Positioner Primary Angle - LAO/RAO");
System.out.println("  (0018,1511) Positioner Secondary Angle - CRAN/CAUD");
System.out.println("  (0018,1114) Magnification Factor");
System.out.println("  (0018,1164) Imager Pixel Spacing - mm/pixel");

System.out.println("X-Ray Acquisition:");
System.out.println("  (0018,0060) KVP");
System.out.println("  (0018,1153) Exposure in µAs");
System.out.println("  (0018,7050) Filter Material - Cu, Al, Mo");

DX/CR (Digital Radiography) Attributes

System.out.println("=== DX/CR (Radiography) ===");

System.out.println("DX Anatomy Imaged Module:");
System.out.println("  (0018,5101) View Position - AP, PA, LL, RL");
System.out.println("  (0008,2218) Anatomic Region Sequence");
System.out.println("  (0020,0060) Laterality - R, L");

System.out.println("DX Positioning Module:");
System.out.println("  (0018,1110) Distance Source to Detector - mm");
System.out.println("  (0018,1111) Distance Source to Patient - mm");
System.out.println("  (0018,1166) Grid - IN, NONE");

System.out.println("Exposure:");
System.out.println("  (0018,0060) KVP");
System.out.println("  (0018,1152) Exposure - mAs");
System.out.println("  (0018,115E) Image Area Dose Product");

MG (Mammography) Attributes

System.out.println("=== MG (Mammography) ===");

System.out.println("Mammography Image Module:");
System.out.println("  (0018,0060) KVP - typically 26-32 kV");
System.out.println("  (0018,7050) Filter Material - Mo, Rh, Al");
System.out.println("  (0018,11A0) Body Part Thickness - mm");
System.out.println("  (0018,11A2) Compression Force - Newtons");
System.out.println("  (0018,7004) Detector Type - DIRECT, SCINTILLATOR");

System.out.println("View Information:");
System.out.println("  (0020,0060) Laterality - R, L");
System.out.println("  (0018,5101) View Position - CC, MLO, ML, LM");
System.out.println("  (0054,0220) View Code Sequence");

NM/PT (Nuclear Medicine/PET) Attributes

System.out.println("=== NM/PT (Nuclear Medicine/PET) ===");

System.out.println("NM Image Module:");
System.out.println("  (0054,0016) Radiopharmaceutical Information Sequence");
System.out.println("  (0018,0031) Radiopharmaceutical - e.g., Tc-99m, FDG");
System.out.println("  (0018,1074) Radionuclide Total Dose - MBq");
System.out.println("  (0018,1072) Radiopharmaceutical Start DateTime");

System.out.println("PET-specific:");
System.out.println("  (0054,1001) Units - BQML, CNTS");
System.out.println("  (0054,1102) Decay Correction - START, ADMIN, NONE");
System.out.println("  (0010,1030) Patient Weight - needed for SUV");
System.out.println("  SUV = Activity / (Injected Dose / Patient Weight)");

Conclusion

Each imaging modality has unique attributes that capture the specific technical parameters and acquisition settings relevant to that modality. Understanding these attributes is essential for building DICOM applications that correctly interpret and display medical images.

When working with multi-modality systems, always check the Modality (0008,0060) attribute first and then apply modality-specific processing based on the relevant IOD (Information Object Definition). In the next tutorial in this series, I will cover DICOMweb for RESTful access to DICOM data. See you then!