DICOM Basics using Java - Key Object Selection (KOS)
Introduction
This is part of my series of articles on the DICOM standard. In this tutorial, we'll explore DICOM Key Object Selection (KOS) documents, which are used to mark significant images for various purposes such as teaching files, quality assurance, clinical review, and study manifests.
KOS documents are based on DICOM Structured Reports and contain references to selected images along with purpose/reason codes.
Prerequisites
Before you begin, ensure you have the following:
- Java JDK installed (Java 8 or later)
- PixelMed Java DICOM Toolkit
- Understanding of DICOM Structured Reports basics
- You can find all the code demonstrated in this tutorial on GitHub here
“The greatest teacher, failure is.” ~ Yoda
The Theory Behind Key Object Selection
Key Object Selection documents solve a fundamental problem in medical imaging workflows: information overload. A CT study might contain 1,000 images, but only 5-10 are diagnostically significant. How do you communicate which ones matter?
The Signal-to-Noise Problem in Large Studies
Modern imaging creates massive datasets:
- CT Angiography: 2,000+ images
- Cardiac MRI: Multiple sequences, hundreds of images
- PET-CT: Combined datasets with thousands of slices
A referring physician shouldn't have to scroll through 2,000 images to find the one showing the patient's pulmonary embolism. KOS documents create a curated subset - a "playlist" of diagnostically important images.
The Manifest Concept
KOS extends beyond marking "interesting" images to serve as a manifest - a definitive list of what should be included in a transaction:
- IHE XDS-I: KOS manifests list images being shared cross-enterprise
- Teaching File Export: KOS lists images selected for educational use
- Quality Review: KOS marks images needing technologist review
The manifest use case enables verification - a receiving system can check that all items listed in the KOS were actually received.
The Rejection Flag Pattern
A powerful use of KOS is marking images for rejection rather than selection. When an image has motion artifact or wrong patient positioning:
- Technologist creates KOS with rejection reason code
- PACS hides rejected image from normal viewing
- Original image is preserved (not deleted) for audit trail
- Repeat exam images are acquired and properly associated
This pattern satisfies both clinical (hide bad images) and legal (preserve audit trail) requirements.
SR Foundation
KOS documents are built on the Structured Report infrastructure - they're essentially minimal SRs containing only IMAGE content items. This means:
- Same parsing infrastructure handles KOS and full SRs
- Purpose codes are coded values (from defined context groups)
- KOS can include text descriptions using TEXT content items
KOS SOP Class
| Element | Value |
|---|---|
| SOP Class UID | 1.2.840.10008.5.1.4.1.1.88.59 |
| Modality | KO |
| Description | Key Object Selection Document |
Common KOS Purpose Codes (CID 7010)
| Code Value | Meaning |
|---|---|
| 113000 | Of Interest |
| 113001 | Rejected for Quality Reasons |
| 113002 | For Referring Provider |
| 113003 | For Surgery |
| 113004 | For Teaching |
| 113005 | For Conference |
| 113008 | For Peer Review |
| 113009 | For Research |
| 113013 | Best In Set |
| 113018 | For Printing |
| 113020 | For Report Attachment |
| 113030 | Manifest |
Creating a Key Object Selection Document
package com.saravanansubramanian.dicom.pixelmedtutorial;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.pixelmed.dicom.*;
public class CreateKeyObjectSelectionDemo {
public static void main(String[] args) {
try {
System.out.println("=== DICOM Key Object Selection Demo ===\n");
// Images to mark as key objects
String[][] selectedImages = {
// {StudyUID, SeriesUID, SOPInstanceUID, SOPClassUID}
{"1.2.3.4.5.6.7.8.9", "1.2.3.4.5.6.7.8.9.1",
"1.2.3.4.5.6.7.8.9.1.1", SOPClass.CTImageStorage},
{"1.2.3.4.5.6.7.8.9", "1.2.3.4.5.6.7.8.9.1",
"1.2.3.4.5.6.7.8.9.1.5", SOPClass.CTImageStorage},
};
String outputFile = "C:\\temp\\key_object_selection.dcm";
// Create the KOS with "Of Interest" purpose
AttributeList kosList = createKeyObjectSelection(
selectedImages,
"113000", // Code value
"DCM", // Coding scheme
"Of Interest" // Code meaning
);
// Add file meta information
FileMetaInformation.addFileMetaInformation(
kosList,
TransferSyntax.ExplicitVRLittleEndian,
"OurAET"
);
// Write to file
kosList.write(outputFile);
System.out.println("Key Object Selection created: " + outputFile);
System.out.println("Number of referenced images: " + selectedImages.length);
} catch (Exception e) {
e.printStackTrace(System.err);
}
}
}
Building the KOS Content Tree
private static AttributeList createKeyObjectSelection(
String[][] selectedImages,
String purposeCodeValue,
String purposeCodingScheme,
String purposeCodeMeaning) throws Exception {
AttributeList list = new AttributeList();
// SOP Class for KOS
Attribute sopClass = new UniqueIdentifierAttribute(TagFromName.SOPClassUID);
sopClass.addValue(SOPClass.KeyObjectSelectionDocumentStorage);
list.put(sopClass);
// Modality = KO (Key Object)
Attribute modality = new CodeStringAttribute(TagFromName.Modality);
modality.addValue("KO");
list.put(modality);
// Build KOS Content Tree
ContentItemFactory cif = new ContentItemFactory();
// Root container with document title
ContentItem root = cif.new ContainerContentItem(
null, null,
new CodedSequenceItem("113030", "DCM", "Key Object Selection"),
true, "DCMR", "2010" // KOS template
);
// Add purpose/flag
ContentItem purposeCode = cif.new CodeContentItem(
root, "HAS CONCEPT MOD",
new CodedSequenceItem("113012", "DCM", "Key Object Description"),
new CodedSequenceItem(purposeCodeValue, purposeCodingScheme, purposeCodeMeaning)
);
// Add each selected image as an IMAGE content item
for (String[] image : selectedImages) {
String instanceUID = image[2];
String classUID = image[3];
ContentItem imageRef = cif.new ImageContentItem(
root, "CONTAINS",
null, // concept name
classUID, // Referenced SOP Class UID
instanceUID, // Referenced SOP Instance UID
0, 0, // frame/segment numbers
null, null // presentation state
);
}
// Convert content tree to attributes
StructuredReport sr = new StructuredReport(root);
list.putAll(sr.getAttributeList());
return list;
}
Use Cases
Key Object Selection documents support various clinical workflows:
Teaching File Export:
1. Radiologist marks interesting cases
2. KOS document lists all selected images
3. Export system retrieves images listed in KOS
4. Anonymized for educational use
Quality Rejection:
1. Technologist marks motion-blurred image
2. KOS with rejection code created
3. PACS hides rejected images from display
4. Maintains audit trail
Referring Physician Report:
1. Radiologist marks key finding images
2. KOS attached to radiology report
3. Physician sees most important images first
4. Improves communication efficiency
Study Manifest:
1. List all images being sent to another system
2. Receiver can verify all images received
3. Ensures complete data transfer
4. Supports IHE XDS-I profile
Rejection Reason Codes (CID 7011)
| Code Value | Meaning |
|---|---|
| 113001 | Rejected for Quality Reasons |
| 113037 | Rejected for Patient Safety |
| 113038 | Incorrect Modality Worklist Entry |
| 113039 | Data Retention Policy Expired |
Conclusion
Key Object Selection documents provide a standardized way to mark and categorize significant images within DICOM. They enable efficient workflows for teaching file creation, quality assurance, clinical communication, and data exchange.
Understanding KOS is particularly important for implementing IHE profiles and building systems that need to track or export selected images from larger studies. In the next tutorial in this series, I will cover DICOM Segmentation objects for storing image segmentation results from AI/ML models. See you then!