PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
kcenon::pacs::services::validation::seg_iod_validator Class Reference

Validator for Segmentation IODs. More...

#include <seg_iod_validator.h>

Collaboration diagram for kcenon::pacs::services::validation::seg_iod_validator:
Collaboration graph

Public Member Functions

 seg_iod_validator ()=default
 Construct validator with default options.
 
 seg_iod_validator (const seg_validation_options &options)
 Construct validator with custom options.
 
validation_result validate (const core::dicom_dataset &dataset) const
 Validate a DICOM dataset against SEG IOD.
 
validation_result validate_segments (const core::dicom_dataset &dataset) const
 Validate segment sequence completeness.
 
validation_result validate_references (const core::dicom_dataset &dataset) const
 Validate referenced instances.
 
bool quick_check (const core::dicom_dataset &dataset) const
 Quick check if dataset has minimum required attributes.
 
const seg_validation_options & options () const noexcept
 Get the validation options.
 
void set_options (const seg_validation_options &options)
 Set validation options.
 

Private Member Functions

void validate_patient_module (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 
void validate_general_study_module (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 
void validate_general_series_module (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 
void validate_segmentation_series_module (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 
void validate_general_equipment_module (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 
void validate_enhanced_general_equipment_module (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 
void validate_general_image_module (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 
void validate_image_pixel_module (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 
void validate_segmentation_image_module (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 
void validate_segment_sequence (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 
void validate_multiframe_functional_groups_module (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 
void validate_multiframe_dimension_module (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 
void validate_common_instance_reference_module (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 
void validate_sop_common_module (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 
void check_type1_attribute (const core::dicom_dataset &dataset, core::dicom_tag tag, std::string_view name, std::vector< validation_finding > &findings) const
 
void check_type2_attribute (const core::dicom_dataset &dataset, core::dicom_tag tag, std::string_view name, std::vector< validation_finding > &findings) const
 
void check_modality (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 
void check_segmentation_type (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 
void check_pixel_data_consistency (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 
void validate_single_segment (const core::dicom_dataset &segment_item, size_t segment_index, std::vector< validation_finding > &findings) const
 

Private Attributes

seg_validation_options options_
 

Detailed Description

Validator for Segmentation IODs.

Validates DICOM datasets against the Segmentation IOD specification. Checks required modules, attributes, segment sequences, and value constraints.

Validated Modules

Mandatory Modules

  • Patient Module (M)
  • Clinical Trial Subject Module (U)
  • General Study Module (M)
  • Patient Study Module (U)
  • General Series Module (M)
  • Segmentation Series Module (M)
  • General Equipment Module (M)
  • Enhanced General Equipment Module (M)
  • General Image Module (M)
  • Image Pixel Module (M)
  • Segmentation Image Module (M)
  • Multi-frame Functional Groups Module (M)
  • Multi-frame Dimension Module (M)
  • Specimen Module (U)
  • Common Instance Reference Module (M)
  • SOP Common Module (M)
Example:
auto result = validator.validate(dataset);
if (!result.is_valid) {
for (const auto& finding : result.findings) {
std::cerr << finding.code << ": " << finding.message << "\n";
}
}
validation_result validate(const core::dicom_dataset &dataset) const
Validate a DICOM dataset against SEG IOD.

Definition at line 112 of file seg_iod_validator.h.

Constructor & Destructor Documentation

◆ seg_iod_validator() [1/2]

kcenon::pacs::services::validation::seg_iod_validator::seg_iod_validator ( )
default

Construct validator with default options.

◆ seg_iod_validator() [2/2]

kcenon::pacs::services::validation::seg_iod_validator::seg_iod_validator ( const seg_validation_options & options)
explicit

Construct validator with custom options.

Parameters
optionsValidation options

Definition at line 81 of file seg_iod_validator.cpp.

82 : options_(options) {}
const seg_validation_options & options() const noexcept
Get the validation options.

Member Function Documentation

◆ check_modality()

void kcenon::pacs::services::validation::seg_iod_validator::check_modality ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private

Definition at line 591 of file seg_iod_validator.cpp.

593 {
594
595 if (!dataset.contains(tags::modality)) {
596 return; // Already reported
597 }
598
599 auto modality = dataset.get_string(tags::modality);
600 if (modality != "SEG") {
601 findings.push_back({
604 "Modality must be 'SEG' for Segmentation objects, found: " + modality,
605 "SEG-ERR-001"
606 });
607 }
608}
auto contains(dicom_tag tag) const noexcept -> bool
Check if the dataset contains an element with the given tag.
auto get_string(dicom_tag tag, std::string_view default_value="") const -> std::string
Get the string value of an element.
constexpr dicom_tag modality
Modality.

References kcenon::pacs::core::dicom_dataset::contains(), kcenon::pacs::services::validation::error, kcenon::pacs::core::dicom_dataset::get_string(), and kcenon::pacs::core::tags::modality.

Referenced by validate_general_series_module().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_pixel_data_consistency()

void kcenon::pacs::services::validation::seg_iod_validator::check_pixel_data_consistency ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private

Definition at line 629 of file seg_iod_validator.cpp.

631 {
632
633 // For SEG, SamplesPerPixel must be 1
634 auto samples = dataset.get_numeric<uint16_t>(tags::samples_per_pixel);
635 if (samples && *samples != 1) {
636 findings.push_back({
639 "SamplesPerPixel must be 1 for Segmentation objects",
640 "SEG-PXL-ERR-001"
641 });
642 }
643
644 // PhotometricInterpretation must be MONOCHROME2
646 auto photometric = dataset.get_string(tags::photometric_interpretation);
647 if (photometric != "MONOCHROME2") {
648 findings.push_back({
651 "PhotometricInterpretation must be MONOCHROME2 for Segmentation",
652 "SEG-PXL-ERR-002"
653 });
654 }
655 }
656
657 // Check BitsAllocated based on SegmentationType
658 auto bits_allocated = dataset.get_numeric<uint16_t>(tags::bits_allocated);
659 auto seg_type = dataset.get_string(seg_tags::segmentation_type);
660
661 if (bits_allocated && !seg_type.empty()) {
662 if (seg_type == "BINARY" && *bits_allocated != 1) {
663 findings.push_back({
666 "BitsAllocated is typically 1 for BINARY segmentation, found: " +
667 std::to_string(*bits_allocated),
668 "SEG-PXL-WARN-001"
669 });
670 }
671
672 if (seg_type == "FRACTIONAL" && *bits_allocated != 8) {
673 findings.push_back({
676 "BitsAllocated is typically 8 for FRACTIONAL segmentation, found: " +
677 std::to_string(*bits_allocated),
678 "SEG-PXL-WARN-002"
679 });
680 }
681 }
682}
auto get_numeric(dicom_tag tag) const -> std::optional< T >
Get the numeric value of an element.
constexpr dicom_tag bits_allocated
Bits Allocated.
constexpr dicom_tag samples_per_pixel
Samples per Pixel.
constexpr dicom_tag photometric_interpretation
Photometric Interpretation.
@ warning
Non-critical - IOD may have issues.

References kcenon::pacs::core::tags::bits_allocated, kcenon::pacs::core::dicom_dataset::contains(), kcenon::pacs::services::validation::error, kcenon::pacs::core::dicom_dataset::get_numeric(), kcenon::pacs::core::dicom_dataset::get_string(), kcenon::pacs::core::tags::photometric_interpretation, kcenon::pacs::core::tags::samples_per_pixel, kcenon::pacs::services::validation::seg_tags::segmentation_type, and kcenon::pacs::services::validation::warning.

Referenced by validate_image_pixel_module().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_segmentation_type()

void kcenon::pacs::services::validation::seg_iod_validator::check_segmentation_type ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private

Definition at line 610 of file seg_iod_validator.cpp.

612 {
613
615 return; // Already reported
616 }
617
618 auto seg_type = dataset.get_string(seg_tags::segmentation_type);
620 findings.push_back({
623 "Invalid SegmentationType value: " + seg_type + " (must be BINARY or FRACTIONAL)",
624 "SEG-ERR-006"
625 });
626 }
627}
bool is_valid_segmentation_type(std::string_view value) noexcept
Check if segmentation type string is valid.

References kcenon::pacs::core::dicom_dataset::contains(), kcenon::pacs::services::validation::error, kcenon::pacs::core::dicom_dataset::get_string(), kcenon::pacs::services::sop_classes::is_valid_segmentation_type(), and kcenon::pacs::services::validation::seg_tags::segmentation_type.

Referenced by validate_segmentation_image_module().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_type1_attribute()

void kcenon::pacs::services::validation::seg_iod_validator::check_type1_attribute ( const core::dicom_dataset & dataset,
core::dicom_tag tag,
std::string_view name,
std::vector< validation_finding > & findings ) const
private

Definition at line 529 of file seg_iod_validator.cpp.

533 {
534
535 if (!dataset.contains(tag)) {
536 findings.push_back({
538 tag,
539 std::string("Type 1 attribute missing: ") + std::string(name) +
540 " (" + tag.to_string() + ")",
541 "SEG-TYPE1-MISSING"
542 });
543 } else {
544 const auto* element = dataset.get(tag);
545 if (element != nullptr) {
546 // For sequences, check if the sequence has items
547 if (element->is_sequence()) {
548 if (element->sequence_items().empty()) {
549 findings.push_back({
551 tag,
552 std::string("Type 1 sequence has no items: ") +
553 std::string(name) + " (" + tag.to_string() + ")",
554 "SEG-TYPE1-EMPTY"
555 });
556 }
557 } else {
558 // For non-sequence elements, check if the value is empty
559 auto value = dataset.get_string(tag);
560 if (value.empty()) {
561 findings.push_back({
563 tag,
564 std::string("Type 1 attribute has empty value: ") +
565 std::string(name) + " (" + tag.to_string() + ")",
566 "SEG-TYPE1-EMPTY"
567 });
568 }
569 }
570 }
571 }
572}
auto get(dicom_tag tag) noexcept -> dicom_element *
Get a pointer to the element with the given tag.
auto to_string() const -> std::string
Convert to string representation.
std::string_view name

References kcenon::pacs::core::dicom_dataset::contains(), kcenon::pacs::services::validation::error, kcenon::pacs::core::dicom_dataset::get(), kcenon::pacs::core::dicom_dataset::get_string(), name, and kcenon::pacs::core::dicom_tag::to_string().

Referenced by validate_enhanced_general_equipment_module(), validate_general_series_module(), validate_general_study_module(), validate_image_pixel_module(), validate_multiframe_dimension_module(), validate_multiframe_functional_groups_module(), validate_segmentation_image_module(), and validate_sop_common_module().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_type2_attribute()

void kcenon::pacs::services::validation::seg_iod_validator::check_type2_attribute ( const core::dicom_dataset & dataset,
core::dicom_tag tag,
std::string_view name,
std::vector< validation_finding > & findings ) const
private

Definition at line 574 of file seg_iod_validator.cpp.

578 {
579
580 if (!dataset.contains(tag)) {
581 findings.push_back({
583 tag,
584 std::string("Type 2 attribute missing: ") + std::string(name) +
585 " (" + tag.to_string() + ")",
586 "SEG-TYPE2-MISSING"
587 });
588 }
589}

References kcenon::pacs::core::dicom_dataset::contains(), name, kcenon::pacs::core::dicom_tag::to_string(), and kcenon::pacs::services::validation::warning.

Referenced by validate_general_equipment_module(), validate_general_image_module(), validate_general_series_module(), validate_general_study_module(), and validate_patient_module().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ options()

const seg_validation_options & kcenon::pacs::services::validation::seg_iod_validator::options ( ) const
nodiscardnoexcept

Get the validation options.

Definition at line 195 of file seg_iod_validator.cpp.

195 {
196 return options_;
197}

References options_.

Referenced by set_options().

Here is the caller graph for this function:

◆ quick_check()

bool kcenon::pacs::services::validation::seg_iod_validator::quick_check ( const core::dicom_dataset & dataset) const
nodiscard

Quick check if dataset has minimum required attributes.

Faster than full validation - only checks Type 1 attributes.

Parameters
datasetThe dataset to check
Returns
true if all Type 1 attributes are present

Definition at line 166 of file seg_iod_validator.cpp.

166 {
167 // Check essential Type 1 attributes for SEG
168
169 // General Study Module
170 if (!dataset.contains(tags::study_instance_uid)) return false;
171
172 // General Series Module
173 if (!dataset.contains(tags::modality)) return false;
174 if (!dataset.contains(tags::series_instance_uid)) return false;
175
176 // Check modality is SEG
177 auto modality = dataset.get_string(tags::modality);
178 if (modality != "SEG") return false;
179
180 // Segmentation Image Module
181 if (!dataset.contains(seg_tags::segmentation_type)) return false;
182 if (!dataset.contains(seg_tags::segment_sequence)) return false;
183
184 // SOP Common Module
185 if (!dataset.contains(tags::sop_class_uid)) return false;
186 if (!dataset.contains(tags::sop_instance_uid)) return false;
187
188 // Verify SOP Class is SEG
189 auto sop_class = dataset.get_string(tags::sop_class_uid);
190 if (!sop_classes::is_seg_storage_sop_class(sop_class)) return false;
191
192 return true;
193}
constexpr dicom_tag sop_instance_uid
SOP Instance UID.
constexpr dicom_tag study_instance_uid
Study Instance UID.
constexpr dicom_tag sop_class_uid
SOP Class UID.
constexpr dicom_tag series_instance_uid
Series Instance UID.
bool is_seg_storage_sop_class(std::string_view uid) noexcept
Check if a SOP Class UID is a SEG Storage SOP Class.

References kcenon::pacs::core::dicom_dataset::contains(), kcenon::pacs::core::dicom_dataset::get_string(), kcenon::pacs::services::sop_classes::is_seg_storage_sop_class(), kcenon::pacs::core::tags::modality, kcenon::pacs::services::validation::seg_tags::segment_sequence, kcenon::pacs::services::validation::seg_tags::segmentation_type, kcenon::pacs::core::tags::series_instance_uid, kcenon::pacs::core::tags::sop_class_uid, kcenon::pacs::core::tags::sop_instance_uid, and kcenon::pacs::core::tags::study_instance_uid.

Referenced by kcenon::pacs::services::validation::is_valid_seg_dataset().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_options()

void kcenon::pacs::services::validation::seg_iod_validator::set_options ( const seg_validation_options & options)

Set validation options.

Definition at line 199 of file seg_iod_validator.cpp.

199 {
201}

References options(), and options_.

Here is the call graph for this function:

◆ validate()

validation_result kcenon::pacs::services::validation::seg_iod_validator::validate ( const core::dicom_dataset & dataset) const
nodiscard

Validate a DICOM dataset against SEG IOD.

Parameters
datasetThe dataset to validate
Returns
Validation result with all findings

Definition at line 84 of file seg_iod_validator.cpp.

84 {
85 validation_result result;
86 result.is_valid = true;
87
88 // Validate mandatory modules
90 validate_patient_module(dataset, result.findings);
91 validate_general_study_module(dataset, result.findings);
92 validate_general_series_module(dataset, result.findings);
93 validate_segmentation_series_module(dataset, result.findings);
94 validate_general_equipment_module(dataset, result.findings);
95 validate_enhanced_general_equipment_module(dataset, result.findings);
96 validate_general_image_module(dataset, result.findings);
97 validate_segmentation_image_module(dataset, result.findings);
98 validate_sop_common_module(dataset, result.findings);
99 }
100
102 validate_segment_sequence(dataset, result.findings);
103 }
104
106 validate_image_pixel_module(dataset, result.findings);
107 }
108
110 validate_common_instance_reference_module(dataset, result.findings);
111 }
112
113 // Multi-frame validation
114 validate_multiframe_functional_groups_module(dataset, result.findings);
115 validate_multiframe_dimension_module(dataset, result.findings);
116
117 // Check for errors
118 for (const auto& finding : result.findings) {
119 if (finding.severity == validation_severity::error) {
120 result.is_valid = false;
121 break;
122 }
123 if (options_.strict_mode && finding.severity == validation_severity::warning) {
124 result.is_valid = false;
125 break;
126 }
127 }
128
129 return result;
130}
void validate_segmentation_series_module(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void validate_general_image_module(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void validate_sop_common_module(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void validate_general_series_module(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void validate_general_study_module(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void validate_common_instance_reference_module(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void validate_patient_module(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void validate_general_equipment_module(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void validate_multiframe_functional_groups_module(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void validate_segment_sequence(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void validate_enhanced_general_equipment_module(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void validate_image_pixel_module(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void validate_multiframe_dimension_module(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void validate_segmentation_image_module(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
bool validate_pixel_data
Validate pixel data matches segmentation type.
bool check_type1
Check Type 1 (required) attributes.
bool validate_segment_sequence
Validate Segment Sequence structure.
bool validate_references
Validate referenced series/instances.
bool strict_mode
Strict mode - treat warnings as errors.
bool check_type2
Check Type 2 (required, can be empty) attributes.

References kcenon::pacs::services::validation::seg_validation_options::check_type1, kcenon::pacs::services::validation::seg_validation_options::check_type2, kcenon::pacs::services::validation::error, kcenon::pacs::services::validation::validation_result::findings, kcenon::pacs::services::validation::validation_result::is_valid, options_, kcenon::pacs::services::validation::seg_validation_options::strict_mode, validate_common_instance_reference_module(), validate_enhanced_general_equipment_module(), validate_general_equipment_module(), validate_general_image_module(), validate_general_series_module(), validate_general_study_module(), validate_image_pixel_module(), validate_multiframe_dimension_module(), validate_multiframe_functional_groups_module(), validate_patient_module(), kcenon::pacs::services::validation::seg_validation_options::validate_pixel_data, kcenon::pacs::services::validation::seg_validation_options::validate_references, validate_segment_sequence(), kcenon::pacs::services::validation::seg_validation_options::validate_segment_sequence, validate_segmentation_image_module(), validate_segmentation_series_module(), validate_sop_common_module(), and kcenon::pacs::services::validation::warning.

Referenced by kcenon::pacs::services::validation::validate_seg_iod().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ validate_common_instance_reference_module()

void kcenon::pacs::services::validation::seg_iod_validator::validate_common_instance_reference_module ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private

Definition at line 485 of file seg_iod_validator.cpp.

487 {
488
489 // Referenced Series Sequence is Type 1C - required if references exist
492 findings.push_back({
495 "ReferencedSeriesSequence (0008,1115) should be present for source image references",
496 "SEG-REF-WARN-001"
497 });
498 }
499 }
500}
bool check_conditional
Check Type 1C/2C (conditionally required) attributes.

References kcenon::pacs::services::validation::seg_validation_options::check_conditional, kcenon::pacs::core::dicom_dataset::contains(), options_, kcenon::pacs::services::validation::seg_tags::referenced_series_sequence_cir, and kcenon::pacs::services::validation::warning.

Referenced by validate(), and validate_references().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ validate_enhanced_general_equipment_module()

void kcenon::pacs::services::validation::seg_iod_validator::validate_enhanced_general_equipment_module ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private

Definition at line 271 of file seg_iod_validator.cpp.

273 {
274
275 if (options_.check_type1) {
276 check_type1_attribute(dataset, seg_tags::manufacturer, "Manufacturer", findings);
277 check_type1_attribute(dataset, seg_tags::manufacturer_model_name, "ManufacturerModelName", findings);
278 check_type1_attribute(dataset, seg_tags::device_serial_number, "DeviceSerialNumber", findings);
279 check_type1_attribute(dataset, seg_tags::software_versions, "SoftwareVersions", findings);
280 }
281}
void check_type1_attribute(const core::dicom_dataset &dataset, core::dicom_tag tag, std::string_view name, std::vector< validation_finding > &findings) const

References kcenon::pacs::services::validation::seg_validation_options::check_type1, check_type1_attribute(), kcenon::pacs::services::validation::seg_tags::device_serial_number, kcenon::pacs::services::validation::seg_tags::manufacturer, kcenon::pacs::services::validation::seg_tags::manufacturer_model_name, options_, and kcenon::pacs::services::validation::seg_tags::software_versions.

Referenced by validate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ validate_general_equipment_module()

void kcenon::pacs::services::validation::seg_iod_validator::validate_general_equipment_module ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private

Definition at line 262 of file seg_iod_validator.cpp.

264 {
265
266 if (options_.check_type2) {
267 check_type2_attribute(dataset, seg_tags::manufacturer, "Manufacturer", findings);
268 }
269}
void check_type2_attribute(const core::dicom_dataset &dataset, core::dicom_tag tag, std::string_view name, std::vector< validation_finding > &findings) const

References kcenon::pacs::services::validation::seg_validation_options::check_type2, check_type2_attribute(), kcenon::pacs::services::validation::seg_tags::manufacturer, and options_.

Referenced by validate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ validate_general_image_module()

void kcenon::pacs::services::validation::seg_iod_validator::validate_general_image_module ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private

Definition at line 283 of file seg_iod_validator.cpp.

285 {
286
287 if (options_.check_type2) {
288 constexpr dicom_tag instance_number{0x0020, 0x0013};
289 check_type2_attribute(dataset, instance_number, "InstanceNumber", findings);
290 }
291}
constexpr dicom_tag instance_number
Instance Number.

References kcenon::pacs::services::validation::seg_validation_options::check_type2, check_type2_attribute(), and options_.

Referenced by validate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ validate_general_series_module()

void kcenon::pacs::services::validation::seg_iod_validator::validate_general_series_module ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private

Definition at line 236 of file seg_iod_validator.cpp.

238 {
239
240 if (options_.check_type1) {
241 check_type1_attribute(dataset, tags::modality, "Modality", findings);
242 check_type1_attribute(dataset, tags::series_instance_uid, "SeriesInstanceUID", findings);
243 check_modality(dataset, findings);
244
245 // Frame of Reference Module - Type 1 for SEG
246 check_type1_attribute(dataset, tags::frame_of_reference_uid, "FrameOfReferenceUID", findings);
247 }
248
249 if (options_.check_type2) {
250 check_type2_attribute(dataset, tags::series_number, "SeriesNumber", findings);
251 }
252}
void check_modality(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
constexpr dicom_tag frame_of_reference_uid
Frame of Reference UID.
constexpr dicom_tag series_number
Series Number.

References check_modality(), kcenon::pacs::services::validation::seg_validation_options::check_type1, check_type1_attribute(), kcenon::pacs::services::validation::seg_validation_options::check_type2, check_type2_attribute(), kcenon::pacs::core::tags::frame_of_reference_uid, kcenon::pacs::core::tags::modality, options_, kcenon::pacs::core::tags::series_instance_uid, and kcenon::pacs::core::tags::series_number.

Referenced by validate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ validate_general_study_module()

void kcenon::pacs::services::validation::seg_iod_validator::validate_general_study_module ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private

Definition at line 219 of file seg_iod_validator.cpp.

221 {
222
223 if (options_.check_type1) {
224 check_type1_attribute(dataset, tags::study_instance_uid, "StudyInstanceUID", findings);
225 }
226
227 if (options_.check_type2) {
228 check_type2_attribute(dataset, tags::study_date, "StudyDate", findings);
229 check_type2_attribute(dataset, tags::study_time, "StudyTime", findings);
230 check_type2_attribute(dataset, tags::referring_physician_name, "ReferringPhysicianName", findings);
231 check_type2_attribute(dataset, tags::study_id, "StudyID", findings);
232 check_type2_attribute(dataset, tags::accession_number, "AccessionNumber", findings);
233 }
234}
constexpr dicom_tag referring_physician_name
Referring Physician's Name.
constexpr dicom_tag accession_number
Accession Number.
constexpr dicom_tag study_time
Study Time.
constexpr dicom_tag study_id
Study ID.
constexpr dicom_tag study_date
Study Date.

References kcenon::pacs::core::tags::accession_number, kcenon::pacs::services::validation::seg_validation_options::check_type1, check_type1_attribute(), kcenon::pacs::services::validation::seg_validation_options::check_type2, check_type2_attribute(), options_, kcenon::pacs::core::tags::referring_physician_name, kcenon::pacs::core::tags::study_date, kcenon::pacs::core::tags::study_id, kcenon::pacs::core::tags::study_instance_uid, and kcenon::pacs::core::tags::study_time.

Referenced by validate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ validate_image_pixel_module()

void kcenon::pacs::services::validation::seg_iod_validator::validate_image_pixel_module ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private

Definition at line 293 of file seg_iod_validator.cpp.

295 {
296
297 if (options_.check_type1) {
298 check_type1_attribute(dataset, tags::samples_per_pixel, "SamplesPerPixel", findings);
299 check_type1_attribute(dataset, tags::photometric_interpretation, "PhotometricInterpretation", findings);
300 check_type1_attribute(dataset, tags::rows, "Rows", findings);
301 check_type1_attribute(dataset, tags::columns, "Columns", findings);
302 check_type1_attribute(dataset, tags::bits_allocated, "BitsAllocated", findings);
303 check_type1_attribute(dataset, tags::bits_stored, "BitsStored", findings);
304 check_type1_attribute(dataset, tags::high_bit, "HighBit", findings);
305 check_type1_attribute(dataset, tags::pixel_representation, "PixelRepresentation", findings);
306 }
307
308 // SEG-specific pixel data constraints
309 check_pixel_data_consistency(dataset, findings);
310}
void check_pixel_data_consistency(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
constexpr dicom_tag high_bit
High Bit.
constexpr dicom_tag rows
Rows.
constexpr dicom_tag columns
Columns.
constexpr dicom_tag bits_stored
Bits Stored.
constexpr dicom_tag pixel_representation
Pixel Representation.

References kcenon::pacs::core::tags::bits_allocated, kcenon::pacs::core::tags::bits_stored, check_pixel_data_consistency(), kcenon::pacs::services::validation::seg_validation_options::check_type1, check_type1_attribute(), kcenon::pacs::core::tags::columns, kcenon::pacs::core::tags::high_bit, options_, kcenon::pacs::core::tags::photometric_interpretation, kcenon::pacs::core::tags::pixel_representation, kcenon::pacs::core::tags::rows, and kcenon::pacs::core::tags::samples_per_pixel.

Referenced by validate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ validate_multiframe_dimension_module()

void kcenon::pacs::services::validation::seg_iod_validator::validate_multiframe_dimension_module ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private

Definition at line 473 of file seg_iod_validator.cpp.

475 {
476
477 if (options_.check_type1) {
479 "DimensionOrganizationSequence", findings);
481 "DimensionIndexSequence", findings);
482 }
483}

References kcenon::pacs::services::validation::seg_validation_options::check_type1, check_type1_attribute(), kcenon::pacs::services::validation::seg_tags::dimension_index_sequence, kcenon::pacs::services::validation::seg_tags::dimension_organization_sequence, and options_.

Referenced by validate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ validate_multiframe_functional_groups_module()

void kcenon::pacs::services::validation::seg_iod_validator::validate_multiframe_functional_groups_module ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private

◆ validate_patient_module()

void kcenon::pacs::services::validation::seg_iod_validator::validate_patient_module ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private

Definition at line 207 of file seg_iod_validator.cpp.

209 {
210
211 if (options_.check_type2) {
212 check_type2_attribute(dataset, tags::patient_name, "PatientName", findings);
213 check_type2_attribute(dataset, tags::patient_id, "PatientID", findings);
214 check_type2_attribute(dataset, tags::patient_birth_date, "PatientBirthDate", findings);
215 check_type2_attribute(dataset, tags::patient_sex, "PatientSex", findings);
216 }
217}
constexpr dicom_tag patient_id
Patient ID.
constexpr dicom_tag patient_birth_date
Patient's Birth Date.
constexpr dicom_tag patient_sex
Patient's Sex.
constexpr dicom_tag patient_name
Patient's Name.

References kcenon::pacs::services::validation::seg_validation_options::check_type2, check_type2_attribute(), options_, kcenon::pacs::core::tags::patient_birth_date, kcenon::pacs::core::tags::patient_id, kcenon::pacs::core::tags::patient_name, and kcenon::pacs::core::tags::patient_sex.

Referenced by validate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ validate_references()

validation_result kcenon::pacs::services::validation::seg_iod_validator::validate_references ( const core::dicom_dataset & dataset) const
nodiscard

Validate referenced instances.

Checks that all referenced series and instances are properly specified.

Parameters
datasetThe dataset to validate
Returns
Validation result for references

Definition at line 150 of file seg_iod_validator.cpp.

150 {
151 validation_result result;
152 result.is_valid = true;
153
154 validate_common_instance_reference_module(dataset, result.findings);
155
156 for (const auto& finding : result.findings) {
157 if (finding.severity == validation_severity::error) {
158 result.is_valid = false;
159 break;
160 }
161 }
162
163 return result;
164}

References kcenon::pacs::services::validation::error, kcenon::pacs::services::validation::validation_result::findings, kcenon::pacs::services::validation::validation_result::is_valid, and validate_common_instance_reference_module().

Here is the call graph for this function:

◆ validate_segment_sequence()

void kcenon::pacs::services::validation::seg_iod_validator::validate_segment_sequence ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private

Definition at line 352 of file seg_iod_validator.cpp.

354 {
355
356 if (!dataset.contains(seg_tags::segment_sequence)) {
357 // Already reported as Type 1 missing
358 return;
359 }
360
361 // Get sequence items
362 const auto* element = dataset.get(seg_tags::segment_sequence);
363 if (!element || !element->is_sequence() || element->sequence_items().empty()) {
364 findings.push_back({
367 "SegmentSequence must contain at least one segment",
368 "SEG-ERR-004"
369 });
370 return;
371 }
372
373 // Validate each segment
374 const auto& sequence = element->sequence_items();
375 for (size_t i = 0; i < sequence.size(); ++i) {
376 const auto& segment_item = sequence[i];
377 validate_single_segment(segment_item, i, findings);
378 }
379}
void validate_single_segment(const core::dicom_dataset &segment_item, size_t segment_index, std::vector< validation_finding > &findings) const

References kcenon::pacs::core::dicom_dataset::contains(), kcenon::pacs::services::validation::error, kcenon::pacs::core::dicom_dataset::get(), kcenon::pacs::services::validation::seg_tags::segment_sequence, and validate_single_segment().

Referenced by validate(), and validate_segments().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ validate_segmentation_image_module()

void kcenon::pacs::services::validation::seg_iod_validator::validate_segmentation_image_module ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private

Definition at line 312 of file seg_iod_validator.cpp.

314 {
315
316 if (options_.check_type1) {
317 check_type1_attribute(dataset, seg_tags::segmentation_type, "SegmentationType", findings);
318 check_type1_attribute(dataset, seg_tags::segment_sequence, "SegmentSequence", findings);
319 }
320
321 // Validate segmentation type value
322 check_segmentation_type(dataset, findings);
323
324 // Check conditional attributes based on segmentation type
326 auto seg_type = dataset.get_string(seg_tags::segmentation_type);
327
328 if (seg_type == "FRACTIONAL") {
329 // MaxFractionalValue is Type 1 for FRACTIONAL
331 findings.push_back({
334 "MaxFractionalValue (0062,000E) is required when SegmentationType is FRACTIONAL",
335 "SEG-ERR-002"
336 });
337 }
338
339 // SegmentationFractionalType is Type 1 for FRACTIONAL
341 findings.push_back({
344 "SegmentationFractionalType (0062,0010) is required when SegmentationType is FRACTIONAL",
345 "SEG-ERR-003"
346 });
347 }
348 }
349 }
350}
void check_segmentation_type(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const

References kcenon::pacs::services::validation::seg_validation_options::check_conditional, check_segmentation_type(), kcenon::pacs::services::validation::seg_validation_options::check_type1, check_type1_attribute(), kcenon::pacs::core::dicom_dataset::contains(), kcenon::pacs::services::validation::error, kcenon::pacs::core::dicom_dataset::get_string(), kcenon::pacs::services::validation::seg_tags::max_fractional_value, options_, kcenon::pacs::services::validation::seg_tags::segment_sequence, kcenon::pacs::services::validation::seg_tags::segmentation_fractional_type, and kcenon::pacs::services::validation::seg_tags::segmentation_type.

Referenced by validate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ validate_segmentation_series_module()

void kcenon::pacs::services::validation::seg_iod_validator::validate_segmentation_series_module ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private

Definition at line 254 of file seg_iod_validator.cpp.

256 {
257
258 // Modality must be "SEG" - already checked in general series validation
259 // This module primarily constrains Modality to SEG
260}

Referenced by validate().

Here is the caller graph for this function:

◆ validate_segments()

validation_result kcenon::pacs::services::validation::seg_iod_validator::validate_segments ( const core::dicom_dataset & dataset) const
nodiscard

Validate segment sequence completeness.

Checks that all segments are properly defined with required attributes.

Parameters
datasetThe dataset to validate
Returns
Validation result for segment sequence

Definition at line 133 of file seg_iod_validator.cpp.

133 {
134 validation_result result;
135 result.is_valid = true;
136
137 validate_segment_sequence(dataset, result.findings);
138
139 for (const auto& finding : result.findings) {
140 if (finding.severity == validation_severity::error) {
141 result.is_valid = false;
142 break;
143 }
144 }
145
146 return result;
147}

References kcenon::pacs::services::validation::error, kcenon::pacs::services::validation::validation_result::findings, kcenon::pacs::services::validation::validation_result::is_valid, and validate_segment_sequence().

Here is the call graph for this function:

◆ validate_single_segment()

void kcenon::pacs::services::validation::seg_iod_validator::validate_single_segment ( const core::dicom_dataset & segment_item,
size_t segment_index,
std::vector< validation_finding > & findings ) const
private

Definition at line 381 of file seg_iod_validator.cpp.

384 {
385
386 std::string prefix = "Segment[" + std::to_string(segment_index) + "]: ";
387
388 // Type 1 attributes within segment
389 if (!segment_item.contains(seg_tags::segment_number)) {
390 findings.push_back({
393 prefix + "SegmentNumber (0062,0004) is required",
394 "SEG-SEQ-ERR-001"
395 });
396 }
397
398 if (!segment_item.contains(seg_tags::segment_label)) {
399 findings.push_back({
402 prefix + "SegmentLabel (0062,0005) is required",
403 "SEG-SEQ-ERR-002"
404 });
405 }
406
407 if (!segment_item.contains(seg_tags::segment_algorithm_type)) {
408 findings.push_back({
411 prefix + "SegmentAlgorithmType (0062,0008) is required",
412 "SEG-SEQ-ERR-003"
413 });
415 auto algo_type = segment_item.get_string(seg_tags::segment_algorithm_type);
417 findings.push_back({
420 prefix + "Invalid SegmentAlgorithmType value: " + algo_type,
421 "SEG-SEQ-WARN-001"
422 });
423 }
424 }
425
426 // Segmented Property Category Code Sequence is Type 1
428 findings.push_back({
431 prefix + "SegmentedPropertyCategoryCodeSequence (0062,0003) is required",
432 "SEG-SEQ-ERR-004"
433 });
434 }
435
436 // Segmented Property Type Code Sequence is Type 1
438 findings.push_back({
441 prefix + "SegmentedPropertyTypeCodeSequence (0062,000F) is required",
442 "SEG-SEQ-ERR-005"
443 });
444 }
445
446 // Validate segment label is not empty
448 auto label = segment_item.get_string(seg_tags::segment_label);
449 if (label.empty()) {
450 findings.push_back({
453 prefix + "SegmentLabel should not be empty",
454 "SEG-SEQ-WARN-002"
455 });
456 }
457 }
458}
bool is_valid_segment_algorithm_type(std::string_view value) noexcept
Check if segment algorithm type string is valid.
bool validate_segment_labels
Validate segment labels and descriptions.
bool validate_algorithm_info
Validate segment algorithm identification.

References kcenon::pacs::core::dicom_dataset::contains(), kcenon::pacs::services::validation::error, kcenon::pacs::core::dicom_dataset::get_string(), kcenon::pacs::services::sop_classes::is_valid_segment_algorithm_type(), options_, kcenon::pacs::services::validation::seg_tags::segment_algorithm_type, kcenon::pacs::services::validation::seg_tags::segment_label, kcenon::pacs::services::validation::seg_tags::segment_number, kcenon::pacs::services::validation::seg_tags::segmented_property_category_code_sequence, kcenon::pacs::services::validation::seg_tags::segmented_property_type_code_sequence, kcenon::pacs::services::validation::seg_validation_options::validate_algorithm_info, kcenon::pacs::services::validation::seg_validation_options::validate_segment_labels, and kcenon::pacs::services::validation::warning.

Referenced by validate_segment_sequence().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ validate_sop_common_module()

void kcenon::pacs::services::validation::seg_iod_validator::validate_sop_common_module ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private

Definition at line 502 of file seg_iod_validator.cpp.

504 {
505
506 if (options_.check_type1) {
507 check_type1_attribute(dataset, tags::sop_class_uid, "SOPClassUID", findings);
508 check_type1_attribute(dataset, tags::sop_instance_uid, "SOPInstanceUID", findings);
509 }
510
511 // Validate SOP Class UID is a SEG storage class
512 if (dataset.contains(tags::sop_class_uid)) {
513 auto sop_class = dataset.get_string(tags::sop_class_uid);
515 findings.push_back({
518 "SOPClassUID is not a recognized SEG Storage SOP Class: " + sop_class,
519 "SEG-ERR-005"
520 });
521 }
522 }
523}

References kcenon::pacs::services::validation::seg_validation_options::check_type1, check_type1_attribute(), kcenon::pacs::core::dicom_dataset::contains(), kcenon::pacs::services::validation::error, kcenon::pacs::core::dicom_dataset::get_string(), kcenon::pacs::services::sop_classes::is_seg_storage_sop_class(), options_, kcenon::pacs::core::tags::sop_class_uid, and kcenon::pacs::core::tags::sop_instance_uid.

Referenced by validate().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ options_


The documentation for this class was generated from the following files: