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

Validator for Structured Report IODs. More...

#include <sr_iod_validator.h>

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

Public Member Functions

 sr_iod_validator ()=default
 Construct validator with default options.
 
 sr_iod_validator (const sr_validation_options &options)
 Construct validator with custom options.
 
validation_result validate (const core::dicom_dataset &dataset) const
 Validate a DICOM dataset against SR IOD.
 
validation_result validate_basic_text_sr (const core::dicom_dataset &dataset) const
 Validate a Basic Text SR dataset.
 
validation_result validate_enhanced_sr (const core::dicom_dataset &dataset) const
 Validate an Enhanced SR dataset.
 
validation_result validate_comprehensive_sr (const core::dicom_dataset &dataset) const
 Validate a Comprehensive SR dataset.
 
validation_result validate_key_object_selection (const core::dicom_dataset &dataset) const
 Validate a Key Object Selection document.
 
validation_result validate_content_tree (const core::dicom_dataset &dataset) const
 Validate content tree structure.
 
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 sr_validation_options & options () const noexcept
 Get the validation options.
 
void set_options (const sr_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_sr_document_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_sr_document_general_module (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 
void validate_sr_document_content_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_evidence_sequences (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 
void validate_content_sequence (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 
void validate_content_item (const core::dicom_dataset &item, size_t depth, std::string_view parent_value_type, std::vector< validation_finding > &findings) const
 
void validate_coded_entry (const core::dicom_dataset &coded_entry, std::string_view context, std::vector< validation_finding > &findings) const
 
void validate_text_content_item (const core::dicom_dataset &item, std::vector< validation_finding > &findings) const
 
void validate_code_content_item (const core::dicom_dataset &item, std::vector< validation_finding > &findings) const
 
void validate_num_content_item (const core::dicom_dataset &item, std::vector< validation_finding > &findings) const
 
void validate_image_content_item (const core::dicom_dataset &item, std::vector< validation_finding > &findings) const
 
void validate_scoord_content_item (const core::dicom_dataset &item, std::vector< validation_finding > &findings) const
 
void validate_scoord3d_content_item (const core::dicom_dataset &item, 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_completion_flag (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 
void check_verification_flag (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 

Private Attributes

sr_validation_options options_
 

Detailed Description

Validator for Structured Report IODs.

Validates DICOM datasets against various SR Document IOD specifications. Supports Basic Text SR, Enhanced SR, Comprehensive SR, and specialized SR documents including CAD SR and Key Object Selection.

Validated Modules

Common Modules (All SR Types)

  • Patient Module (M)
  • General Study Module (M)
  • SR Document Series Module (M)
  • General Equipment Module (M)
  • SR Document General Module (M)
  • SR Document Content Module (M)
  • SOP Common Module (M)

Enhanced SR Additional Modules

  • Current Requested Procedure Evidence Sequence (1C)
  • Pertinent Other Evidence Sequence (1C)

Comprehensive SR Additional Modules

  • SCOORD/SCOORD3D support
Example:
sr_iod_validator validator;
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 SR IOD.

Definition at line 117 of file sr_iod_validator.h.

Constructor & Destructor Documentation

◆ sr_iod_validator() [1/2]

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

Construct validator with default options.

◆ sr_iod_validator() [2/2]

kcenon::pacs::services::validation::sr_iod_validator::sr_iod_validator ( const sr_validation_options & options)
explicit

Construct validator with custom options.

Parameters
optionsValidation options

Definition at line 89 of file sr_iod_validator.cpp.

90 : options_(options) {}
const sr_validation_options & options() const noexcept
Get the validation options.

Member Function Documentation

◆ check_completion_flag()

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

Definition at line 918 of file sr_iod_validator.cpp.

920 {
921
922 if (!dataset.contains(sr_tags::completion_flag)) {
923 return;
924 }
925
926 auto flag = dataset.get_string(sr_tags::completion_flag);
927 if (flag != "PARTIAL" && flag != "COMPLETE") {
928 findings.push_back({
931 "Invalid CompletionFlag value: " + flag + " (must be PARTIAL or COMPLETE)",
932 "SR-FLAG-ERR-001"
933 });
934 }
935}
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.

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

Referenced by validate_sr_document_general_module().

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

◆ check_modality()

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

Definition at line 899 of file sr_iod_validator.cpp.

901 {
902
903 if (!dataset.contains(tags::modality)) {
904 return;
905 }
906
907 auto modality = dataset.get_string(tags::modality);
908 if (modality != "SR") {
909 findings.push_back({
912 "Modality must be 'SR' for Structured Report objects, found: " + modality,
913 "SR-ERR-002"
914 });
915 }
916}
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_sr_document_series_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::sr_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 837 of file sr_iod_validator.cpp.

841 {
842
843 if (!dataset.contains(tag)) {
844 findings.push_back({
846 tag,
847 std::string("Type 1 attribute missing: ") + std::string(name) +
848 " (" + tag.to_string() + ")",
849 "SR-TYPE1-MISSING"
850 });
851 } else {
852 const auto* element = dataset.get(tag);
853 if (element != nullptr) {
854 // For sequences, check if the sequence has items
855 if (element->is_sequence()) {
856 if (element->sequence_items().empty()) {
857 findings.push_back({
859 tag,
860 std::string("Type 1 sequence has no items: ") +
861 std::string(name) + " (" + tag.to_string() + ")",
862 "SR-TYPE1-EMPTY"
863 });
864 }
865 } else {
866 // For non-sequence elements, check if the value is empty
867 auto value = dataset.get_string(tag);
868 if (value.empty()) {
869 findings.push_back({
871 tag,
872 std::string("Type 1 attribute has empty value: ") +
873 std::string(name) + " (" + tag.to_string() + ")",
874 "SR-TYPE1-EMPTY"
875 });
876 }
877 }
878 }
879 }
880}
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_general_study_module(), validate_sop_common_module(), validate_sr_document_content_module(), validate_sr_document_general_module(), and validate_sr_document_series_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::sr_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 882 of file sr_iod_validator.cpp.

886 {
887
888 if (!dataset.contains(tag)) {
889 findings.push_back({
891 tag,
892 std::string("Type 2 attribute missing: ") + std::string(name) +
893 " (" + tag.to_string() + ")",
894 "SR-TYPE2-MISSING"
895 });
896 }
897}
@ warning
Non-critical - IOD may have issues.

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_study_module(), validate_patient_module(), validate_sr_document_general_module(), and validate_sr_document_series_module().

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

◆ check_verification_flag()

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

Definition at line 937 of file sr_iod_validator.cpp.

939 {
940
941 if (!dataset.contains(sr_tags::verification_flag)) {
942 return;
943 }
944
945 auto flag = dataset.get_string(sr_tags::verification_flag);
946 if (flag != "UNVERIFIED" && flag != "VERIFIED") {
947 findings.push_back({
950 "Invalid VerificationFlag value: " + flag + " (must be UNVERIFIED or VERIFIED)",
951 "SR-FLAG-ERR-002"
952 });
953 }
954}

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

Referenced by validate_sr_document_general_module().

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

◆ options()

const sr_validation_options & kcenon::pacs::services::validation::sr_iod_validator::options ( ) const
nodiscardnoexcept

Get the validation options.

Definition at line 338 of file sr_iod_validator.cpp.

338 {
339 return options_;
340}

References options_.

Referenced by set_options().

Here is the caller graph for this function:

◆ quick_check()

bool kcenon::pacs::services::validation::sr_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 305 of file sr_iod_validator.cpp.

305 {
306 // Check essential Type 1 attributes
307
308 // General Study Module
309 if (!dataset.contains(tags::study_instance_uid)) return false;
310
311 // General Series Module
312 if (!dataset.contains(tags::modality)) return false;
313 if (!dataset.contains(tags::series_instance_uid)) return false;
314
315 // Check modality is SR
316 auto modality = dataset.get_string(tags::modality);
317 if (modality != "SR") return false;
318
319 // SR Document General Module
320 if (!dataset.contains(sr_tags::completion_flag)) return false;
321 if (!dataset.contains(sr_tags::verification_flag)) return false;
322
323 // SR Document Content Module - root content item
324 if (!dataset.contains(sr_tags::value_type)) return false;
325 if (!dataset.contains(sr_tags::concept_name_code_sequence)) return false;
326
327 // SOP Common Module
328 if (!dataset.contains(tags::sop_class_uid)) return false;
329 if (!dataset.contains(tags::sop_instance_uid)) return false;
330
331 // Verify SOP Class is SR
332 auto sop_class = dataset.get_string(tags::sop_class_uid);
333 if (!sop_classes::is_sr_storage_sop_class(sop_class)) return false;
334
335 return true;
336}
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_sr_storage_sop_class(std::string_view uid) noexcept
Check if a SOP Class UID is an SR Storage SOP Class.

References kcenon::pacs::services::validation::sr_tags::completion_flag, kcenon::pacs::services::validation::sr_tags::concept_name_code_sequence, kcenon::pacs::core::dicom_dataset::contains(), kcenon::pacs::core::dicom_dataset::get_string(), kcenon::pacs::services::sop_classes::is_sr_storage_sop_class(), kcenon::pacs::core::tags::modality, kcenon::pacs::core::tags::series_instance_uid, kcenon::pacs::core::tags::sop_class_uid, kcenon::pacs::core::tags::sop_instance_uid, kcenon::pacs::core::tags::study_instance_uid, kcenon::pacs::services::validation::sr_tags::value_type, and kcenon::pacs::services::validation::sr_tags::verification_flag.

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

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

◆ set_options()

void kcenon::pacs::services::validation::sr_iod_validator::set_options ( const sr_validation_options & options)

Set validation options.

Definition at line 342 of file sr_iod_validator.cpp.

342 {
344}

References options(), and options_.

Here is the call graph for this function:

◆ validate()

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

Validate a DICOM dataset against SR IOD.

Automatically detects the SR type and applies appropriate validation.

Parameters
datasetThe dataset to validate
Returns
Validation result with all findings

Definition at line 92 of file sr_iod_validator.cpp.

92 {
93 // Detect SR type and delegate to appropriate validation
94 if (!dataset.contains(tags::sop_class_uid)) {
95 validation_result result;
96 result.is_valid = false;
97 result.findings.push_back({
100 "SOPClassUID is required to determine SR type",
101 "SR-ERR-000"
102 });
103 return result;
104 }
105
106 auto sop_class = dataset.get_string(tags::sop_class_uid);
107 auto doc_type = sop_classes::get_sr_document_type(sop_class);
108
109 switch (doc_type) {
111 return validate_basic_text_sr(dataset);
113 return validate_enhanced_sr(dataset);
116 return validate_comprehensive_sr(dataset);
118 return validate_key_object_selection(dataset);
119 default:
120 // For other types, use comprehensive validation
121 return validate_comprehensive_sr(dataset);
122 }
123}
validation_result validate_key_object_selection(const core::dicom_dataset &dataset) const
Validate a Key Object Selection document.
validation_result validate_basic_text_sr(const core::dicom_dataset &dataset) const
Validate a Basic Text SR dataset.
validation_result validate_comprehensive_sr(const core::dicom_dataset &dataset) const
Validate a Comprehensive SR dataset.
validation_result validate_enhanced_sr(const core::dicom_dataset &dataset) const
Validate an Enhanced SR dataset.
sr_document_type get_sr_document_type(std::string_view uid) noexcept
Get SR document type for a SOP Class UID.
@ enhanced
Enhanced SR - References to images/waveforms.
@ comprehensive
Comprehensive SR - Complex with spatial coords.
@ comprehensive_3d
Comprehensive 3D SR - 3D spatial coordinates.
@ basic_text
Basic Text SR - Simple text reports.
@ key_object_selection
Key Object Selection - Image selection.

References kcenon::pacs::services::sop_classes::basic_text, kcenon::pacs::services::sop_classes::comprehensive, kcenon::pacs::services::sop_classes::comprehensive_3d, kcenon::pacs::core::dicom_dataset::contains(), kcenon::pacs::services::sop_classes::enhanced, kcenon::pacs::services::validation::error, kcenon::pacs::services::validation::validation_result::findings, kcenon::pacs::services::sop_classes::get_sr_document_type(), kcenon::pacs::core::dicom_dataset::get_string(), kcenon::pacs::services::validation::validation_result::is_valid, kcenon::pacs::services::sop_classes::key_object_selection, kcenon::pacs::core::tags::sop_class_uid, validate_basic_text_sr(), validate_comprehensive_sr(), validate_enhanced_sr(), and validate_key_object_selection().

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

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

◆ validate_basic_text_sr()

validation_result kcenon::pacs::services::validation::sr_iod_validator::validate_basic_text_sr ( const core::dicom_dataset & dataset) const
nodiscard

Validate a Basic Text SR dataset.

Parameters
datasetThe dataset to validate
Returns
Validation result with all findings

Definition at line 126 of file sr_iod_validator.cpp.

126 {
127 validation_result result;
128 result.is_valid = true;
129
130 // Common modules
131 validate_patient_module(dataset, result.findings);
132 validate_general_study_module(dataset, result.findings);
133 validate_sr_document_series_module(dataset, result.findings);
134 validate_general_equipment_module(dataset, result.findings);
135 validate_sr_document_general_module(dataset, result.findings);
136 validate_sr_document_content_module(dataset, result.findings);
137 validate_sop_common_module(dataset, result.findings);
138
139 // Basic Text SR does not support SCOORD, IMAGE, WAVEFORM, etc.
140 // Content validation will handle value type restrictions
141
142 for (const auto& finding : result.findings) {
143 if (finding.severity == validation_severity::error) {
144 result.is_valid = false;
145 break;
146 }
147 if (options_.strict_mode && finding.severity == validation_severity::warning) {
148 result.is_valid = false;
149 break;
150 }
151 }
152
153 return result;
154}
void validate_patient_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_sr_document_general_module(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void validate_sr_document_content_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_sr_document_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
bool strict_mode
Strict mode - treat warnings as errors.

References 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::sr_validation_options::strict_mode, validate_general_equipment_module(), validate_general_study_module(), validate_patient_module(), validate_sop_common_module(), validate_sr_document_content_module(), validate_sr_document_general_module(), validate_sr_document_series_module(), and kcenon::pacs::services::validation::warning.

Referenced by validate().

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

◆ validate_code_content_item()

void kcenon::pacs::services::validation::sr_iod_validator::validate_code_content_item ( const core::dicom_dataset & item,
std::vector< validation_finding > & findings ) const
private

Definition at line 688 of file sr_iod_validator.cpp.

690 {
691
693 findings.push_back({
696 "ConceptNameCodeSequence is required for CODE content item",
697 "SR-CODE-ITEM-ERR-001"
698 });
699 }
700}
constexpr dicom_tag item
Item.

References kcenon::pacs::services::validation::sr_tags::concept_name_code_sequence, and kcenon::pacs::services::validation::error.

Referenced by validate_content_item().

Here is the caller graph for this function:

◆ validate_coded_entry()

void kcenon::pacs::services::validation::sr_iod_validator::validate_coded_entry ( const core::dicom_dataset & coded_entry,
std::string_view context,
std::vector< validation_finding > & findings ) const
private

Definition at line 638 of file sr_iod_validator.cpp.

641 {
642
643 // Code Value
644 if (!coded_entry.contains(sr_tags::code_value)) {
645 findings.push_back({
648 std::string(context) + ": CodeValue is required",
649 "SR-CODE-ERR-001"
650 });
651 }
652
653 // Coding Scheme Designator
655 findings.push_back({
658 std::string(context) + ": CodingSchemeDesignator is required",
659 "SR-CODE-ERR-002"
660 });
661 }
662
663 // Code Meaning
664 if (!coded_entry.contains(sr_tags::code_meaning)) {
665 findings.push_back({
668 std::string(context) + ": CodeMeaning is required",
669 "SR-CODE-ERR-003"
670 });
671 }
672}

References kcenon::pacs::services::validation::sr_tags::code_meaning, kcenon::pacs::services::validation::sr_tags::code_value, kcenon::pacs::services::validation::sr_tags::coding_scheme_designator, kcenon::pacs::core::dicom_dataset::contains(), and kcenon::pacs::services::validation::error.

Referenced by validate_sr_document_content_module().

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

◆ validate_comprehensive_sr()

validation_result kcenon::pacs::services::validation::sr_iod_validator::validate_comprehensive_sr ( const core::dicom_dataset & dataset) const
nodiscard

Validate a Comprehensive SR dataset.

Parameters
datasetThe dataset to validate
Returns
Validation result with all findings

Definition at line 190 of file sr_iod_validator.cpp.

190 {
191 validation_result result;
192 result.is_valid = true;
193
194 // Common modules
195 validate_patient_module(dataset, result.findings);
196 validate_general_study_module(dataset, result.findings);
197 validate_sr_document_series_module(dataset, result.findings);
198 validate_general_equipment_module(dataset, result.findings);
199 validate_sr_document_general_module(dataset, result.findings);
200 validate_sr_document_content_module(dataset, result.findings);
201 validate_sop_common_module(dataset, result.findings);
202
203 // Comprehensive SR specific - evidence sequences
205 validate_evidence_sequences(dataset, result.findings);
206 }
207
208 // Content tree validation (includes SCOORD support)
210 validate_content_sequence(dataset, result.findings);
211 }
212
213 for (const auto& finding : result.findings) {
214 if (finding.severity == validation_severity::error) {
215 result.is_valid = false;
216 break;
217 }
218 if (options_.strict_mode && finding.severity == validation_severity::warning) {
219 result.is_valid = false;
220 break;
221 }
222 }
223
224 return result;
225}
void validate_evidence_sequences(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void validate_content_sequence(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
bool validate_references
Validate referenced SOP instances.
bool validate_content_sequence
Validate Content Sequence structure.

References 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::sr_validation_options::strict_mode, validate_content_sequence(), kcenon::pacs::services::validation::sr_validation_options::validate_content_sequence, validate_evidence_sequences(), validate_general_equipment_module(), validate_general_study_module(), validate_patient_module(), kcenon::pacs::services::validation::sr_validation_options::validate_references, validate_sop_common_module(), validate_sr_document_content_module(), validate_sr_document_general_module(), validate_sr_document_series_module(), and kcenon::pacs::services::validation::warning.

Referenced by validate().

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

◆ validate_content_item()

void kcenon::pacs::services::validation::sr_iod_validator::validate_content_item ( const core::dicom_dataset & item,
size_t depth,
std::string_view parent_value_type,
std::vector< validation_finding > & findings ) const
private

Definition at line 552 of file sr_iod_validator.cpp.

556 {
557
558 // Prevent infinite recursion
559 if (depth > 100) {
560 findings.push_back({
563 "Content tree depth exceeds 100 - possible circular reference",
564 "SR-CONTENT-WARN-001"
565 });
566 return;
567 }
568
569 // Check required attributes
570 if (!item.contains(sr_tags::relationship_type)) {
571 findings.push_back({
574 "RelationshipType missing in content item at depth " + std::to_string(depth),
575 "SR-ITEM-ERR-001"
576 });
577 }
578
579 if (!item.contains(sr_tags::value_type)) {
580 findings.push_back({
583 "ValueType missing in content item at depth " + std::to_string(depth),
584 "SR-ITEM-ERR-002"
585 });
586 return; // Can't validate further without value type
587 }
588
589 auto value_type = item.get_string(sr_tags::value_type);
590 auto sr_vt = sop_classes::parse_sr_value_type(value_type);
591
593 findings.push_back({
596 "Invalid ValueType: " + value_type,
597 "SR-ITEM-ERR-003"
598 });
599 return;
600 }
601
602 // Value type specific validation
603 switch (sr_vt) {
605 validate_text_content_item(item, findings);
606 break;
608 validate_code_content_item(item, findings);
609 break;
611 validate_num_content_item(item, findings);
612 break;
614 validate_image_content_item(item, findings);
615 break;
617 validate_scoord_content_item(item, findings);
618 break;
620 validate_scoord3d_content_item(item, findings);
621 break;
622 default:
623 break;
624 }
625
626 // Validate nested content items
627 if (item.contains(sr_tags::content_sequence)) {
628 const auto* nested_elem = item.get(sr_tags::content_sequence);
629 if (nested_elem && nested_elem->is_sequence()) {
630 const auto& nested_seq = nested_elem->sequence_items();
631 for (size_t i = 0; i < nested_seq.size(); ++i) {
632 validate_content_item(nested_seq[i], depth + 1, value_type, findings);
633 }
634 }
635 }
636}
void validate_image_content_item(const core::dicom_dataset &item, std::vector< validation_finding > &findings) const
void validate_num_content_item(const core::dicom_dataset &item, std::vector< validation_finding > &findings) const
void validate_text_content_item(const core::dicom_dataset &item, std::vector< validation_finding > &findings) const
void validate_scoord_content_item(const core::dicom_dataset &item, std::vector< validation_finding > &findings) const
void validate_content_item(const core::dicom_dataset &item, size_t depth, std::string_view parent_value_type, std::vector< validation_finding > &findings) const
void validate_code_content_item(const core::dicom_dataset &item, std::vector< validation_finding > &findings) const
void validate_scoord3d_content_item(const core::dicom_dataset &item, std::vector< validation_finding > &findings) const
constexpr dicom_tag value_type
sr_value_type parse_sr_value_type(std::string_view value) noexcept
Parse SR value type from DICOM string.
@ scoord
SCOORD - Spatial coordinates (2D)
@ scoord3d
SCOORD3D - Spatial coordinates (3D)

References kcenon::pacs::services::sop_classes::code, kcenon::pacs::services::validation::sr_tags::content_sequence, kcenon::pacs::services::validation::error, kcenon::pacs::services::sop_classes::image, kcenon::pacs::services::sop_classes::num, kcenon::pacs::services::sop_classes::parse_sr_value_type(), kcenon::pacs::services::validation::sr_tags::relationship_type, kcenon::pacs::services::sop_classes::scoord, kcenon::pacs::services::sop_classes::scoord3d, kcenon::pacs::services::sop_classes::text, kcenon::pacs::services::sop_classes::unknown, validate_code_content_item(), validate_content_item(), validate_image_content_item(), validate_num_content_item(), validate_scoord3d_content_item(), validate_scoord_content_item(), validate_text_content_item(), kcenon::pacs::services::validation::sr_tags::value_type, and kcenon::pacs::services::validation::warning.

Referenced by validate_content_item(), and validate_content_sequence().

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

◆ validate_content_sequence()

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

Definition at line 517 of file sr_iod_validator.cpp.

519 {
520
521 if (!dataset.contains(sr_tags::content_sequence)) {
522 findings.push_back({
525 "ContentSequence not present - SR document has no content items",
526 "SR-CONTENT-INFO-001"
527 });
528 return;
529 }
530
531 const auto* content_elem = dataset.get(sr_tags::content_sequence);
532 if (!content_elem || !content_elem->is_sequence() || content_elem->sequence_items().empty()) {
533 findings.push_back({
536 "ContentSequence is empty",
537 "SR-CONTENT-INFO-002"
538 });
539 return;
540 }
541
542 // Get root value type for context
543 auto root_value_type = dataset.get_string(sr_tags::value_type);
544
545 // Validate each content item
546 const auto& content_seq = content_elem->sequence_items();
547 for (size_t i = 0; i < content_seq.size(); ++i) {
548 validate_content_item(content_seq[i], 1, root_value_type, findings);
549 }
550}
@ info
Informational - suggestion for improvement.

References kcenon::pacs::core::dicom_dataset::contains(), kcenon::pacs::services::validation::sr_tags::content_sequence, kcenon::pacs::core::dicom_dataset::get(), kcenon::pacs::core::dicom_dataset::get_string(), kcenon::pacs::services::validation::info, validate_content_item(), and kcenon::pacs::services::validation::sr_tags::value_type.

Referenced by validate_comprehensive_sr(), validate_content_tree(), and validate_sr_document_content_module().

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

◆ validate_content_tree()

validation_result kcenon::pacs::services::validation::sr_iod_validator::validate_content_tree ( const core::dicom_dataset & dataset) const
nodiscard

Validate content tree structure.

Validates the Content Sequence hierarchy and relationships.

Parameters
datasetThe dataset to validate
Returns
Validation result for content tree

Definition at line 272 of file sr_iod_validator.cpp.

272 {
273 validation_result result;
274 result.is_valid = true;
275
276 validate_content_sequence(dataset, result.findings);
277
278 for (const auto& finding : result.findings) {
279 if (finding.severity == validation_severity::error) {
280 result.is_valid = false;
281 break;
282 }
283 }
284
285 return result;
286}

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

Here is the call graph for this function:

◆ validate_enhanced_sr()

validation_result kcenon::pacs::services::validation::sr_iod_validator::validate_enhanced_sr ( const core::dicom_dataset & dataset) const
nodiscard

Validate an Enhanced SR dataset.

Parameters
datasetThe dataset to validate
Returns
Validation result with all findings

Definition at line 157 of file sr_iod_validator.cpp.

157 {
158 validation_result result;
159 result.is_valid = true;
160
161 // Common modules
162 validate_patient_module(dataset, result.findings);
163 validate_general_study_module(dataset, result.findings);
164 validate_sr_document_series_module(dataset, result.findings);
165 validate_general_equipment_module(dataset, result.findings);
166 validate_sr_document_general_module(dataset, result.findings);
167 validate_sr_document_content_module(dataset, result.findings);
168 validate_sop_common_module(dataset, result.findings);
169
170 // Enhanced SR specific - evidence sequences
172 validate_evidence_sequences(dataset, result.findings);
173 }
174
175 for (const auto& finding : result.findings) {
176 if (finding.severity == validation_severity::error) {
177 result.is_valid = false;
178 break;
179 }
180 if (options_.strict_mode && finding.severity == validation_severity::warning) {
181 result.is_valid = false;
182 break;
183 }
184 }
185
186 return result;
187}

References 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::sr_validation_options::strict_mode, validate_evidence_sequences(), validate_general_equipment_module(), validate_general_study_module(), validate_patient_module(), kcenon::pacs::services::validation::sr_validation_options::validate_references, validate_sop_common_module(), validate_sr_document_content_module(), validate_sr_document_general_module(), validate_sr_document_series_module(), and kcenon::pacs::services::validation::warning.

Referenced by validate().

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

◆ validate_evidence_sequences()

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

Definition at line 499 of file sr_iod_validator.cpp.

501 {
502
503 // For Enhanced/Comprehensive SR, at least one evidence sequence should be present
506
507 if (!has_evidence) {
508 findings.push_back({
511 "No evidence sequences present - SR may not properly link to source images",
512 "SR-EVIDENCE-INFO-001"
513 });
514 }
515}
constexpr dicom_tag current_requested_procedure_evidence_sequence

References kcenon::pacs::core::dicom_dataset::contains(), kcenon::pacs::services::validation::sr_tags::current_requested_procedure_evidence_sequence, kcenon::pacs::services::validation::info, and kcenon::pacs::services::validation::sr_tags::pertinent_other_evidence_sequence.

Referenced by validate_comprehensive_sr(), validate_enhanced_sr(), and validate_references().

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::sr_iod_validator::validate_general_equipment_module ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private

Definition at line 394 of file sr_iod_validator.cpp.

396 {
397
398 constexpr dicom_tag manufacturer{0x0008, 0x0070};
399 if (options_.check_type2) {
400 check_type2_attribute(dataset, manufacturer, "Manufacturer", findings);
401 }
402}
void check_type2_attribute(const core::dicom_dataset &dataset, core::dicom_tag tag, std::string_view name, std::vector< validation_finding > &findings) const
constexpr dicom_tag manufacturer
Manufacturer.
bool check_type2
Check Type 2 (required, can be empty) attributes.

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

Referenced by validate_basic_text_sr(), validate_comprehensive_sr(), validate_enhanced_sr(), and validate_key_object_selection().

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::sr_iod_validator::validate_general_study_module ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private

Definition at line 362 of file sr_iod_validator.cpp.

364 {
365
366 if (options_.check_type1) {
367 check_type1_attribute(dataset, tags::study_instance_uid, "StudyInstanceUID", findings);
368 }
369
370 if (options_.check_type2) {
371 check_type2_attribute(dataset, tags::study_date, "StudyDate", findings);
372 check_type2_attribute(dataset, tags::study_time, "StudyTime", findings);
373 check_type2_attribute(dataset, tags::referring_physician_name, "ReferringPhysicianName", findings);
374 check_type2_attribute(dataset, tags::study_id, "StudyID", findings);
375 check_type2_attribute(dataset, tags::accession_number, "AccessionNumber", findings);
376 }
377}
void check_type1_attribute(const core::dicom_dataset &dataset, core::dicom_tag tag, std::string_view name, std::vector< validation_finding > &findings) const
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.
bool check_type1
Check Type 1 (required) attributes.

References kcenon::pacs::core::tags::accession_number, kcenon::pacs::services::validation::sr_validation_options::check_type1, check_type1_attribute(), kcenon::pacs::services::validation::sr_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_basic_text_sr(), validate_comprehensive_sr(), validate_enhanced_sr(), and validate_key_object_selection().

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

◆ validate_image_content_item()

void kcenon::pacs::services::validation::sr_iod_validator::validate_image_content_item ( const core::dicom_dataset & item,
std::vector< validation_finding > & findings ) const
private

Definition at line 740 of file sr_iod_validator.cpp.

742 {
743
744 if (!item.contains(sr_tags::referenced_sop_sequence)) {
745 findings.push_back({
748 "ReferencedSOPSequence is required for IMAGE content item",
749 "SR-IMAGE-ERR-001"
750 });
751 return;
752 }
753
754 const auto* ref_elem = item.get(sr_tags::referenced_sop_sequence);
755 if (ref_elem && ref_elem->is_sequence() && !ref_elem->sequence_items().empty()) {
756 const auto& ref_item = ref_elem->sequence_items()[0];
757
758 if (!ref_item.contains(sr_tags::referenced_sop_class_uid)) {
759 findings.push_back({
762 "ReferencedSOPClassUID is required in IMAGE reference",
763 "SR-IMAGE-ERR-002"
764 });
765 }
766
767 if (!ref_item.contains(sr_tags::referenced_sop_instance_uid)) {
768 findings.push_back({
771 "ReferencedSOPInstanceUID is required in IMAGE reference",
772 "SR-IMAGE-ERR-003"
773 });
774 }
775 }
776}

References kcenon::pacs::services::validation::error, kcenon::pacs::services::validation::sr_tags::referenced_sop_class_uid, kcenon::pacs::services::validation::sr_tags::referenced_sop_instance_uid, and kcenon::pacs::services::validation::sr_tags::referenced_sop_sequence.

Referenced by validate_content_item().

Here is the caller graph for this function:

◆ validate_key_object_selection()

validation_result kcenon::pacs::services::validation::sr_iod_validator::validate_key_object_selection ( const core::dicom_dataset & dataset) const
nodiscard

Validate a Key Object Selection document.

Parameters
datasetThe dataset to validate
Returns
Validation result with all findings

Definition at line 228 of file sr_iod_validator.cpp.

228 {
229 validation_result result;
230 result.is_valid = true;
231
233 return result;
234 }
235
236 // Common modules
237 validate_patient_module(dataset, result.findings);
238 validate_general_study_module(dataset, result.findings);
239 validate_sr_document_series_module(dataset, result.findings);
240 validate_general_equipment_module(dataset, result.findings);
241 validate_sr_document_general_module(dataset, result.findings);
242 validate_sr_document_content_module(dataset, result.findings);
243 validate_sop_common_module(dataset, result.findings);
244
245 // KOS must have Current Requested Procedure Evidence Sequence
246 if (options_.check_type1) {
248 result.findings.push_back({
251 "CurrentRequestedProcedureEvidenceSequence is required for Key Object Selection",
252 "SR-KOS-ERR-001"
253 });
254 }
255 }
256
257 for (const auto& finding : result.findings) {
258 if (finding.severity == validation_severity::error) {
259 result.is_valid = false;
260 break;
261 }
262 if (options_.strict_mode && finding.severity == validation_severity::warning) {
263 result.is_valid = false;
264 break;
265 }
266 }
267
268 return result;
269}
bool validate_key_object_selection
Allow Key Object Selection document specific validation.

References kcenon::pacs::services::validation::sr_validation_options::check_type1, kcenon::pacs::core::dicom_dataset::contains(), kcenon::pacs::services::validation::sr_tags::current_requested_procedure_evidence_sequence, 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::sr_validation_options::strict_mode, validate_general_equipment_module(), validate_general_study_module(), kcenon::pacs::services::validation::sr_validation_options::validate_key_object_selection, validate_patient_module(), validate_sop_common_module(), validate_sr_document_content_module(), validate_sr_document_general_module(), validate_sr_document_series_module(), and kcenon::pacs::services::validation::warning.

Referenced by validate().

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

◆ validate_num_content_item()

void kcenon::pacs::services::validation::sr_iod_validator::validate_num_content_item ( const core::dicom_dataset & item,
std::vector< validation_finding > & findings ) const
private

Definition at line 702 of file sr_iod_validator.cpp.

704 {
705
706 if (!item.contains(sr_tags::measured_value_sequence)) {
707 findings.push_back({
710 "MeasuredValueSequence is required for NUM content item",
711 "SR-NUM-ERR-001"
712 });
713 return;
714 }
715
716 const auto* measured_elem = item.get(sr_tags::measured_value_sequence);
717 if (measured_elem && measured_elem->is_sequence() && !measured_elem->sequence_items().empty()) {
718 const auto& mv_item = measured_elem->sequence_items()[0];
719
720 if (!mv_item.contains(sr_tags::numeric_value)) {
721 findings.push_back({
724 "NumericValue is required in MeasuredValueSequence",
725 "SR-NUM-ERR-002"
726 });
727 }
728
729 if (!mv_item.contains(sr_tags::measurement_units_code_sequence)) {
730 findings.push_back({
733 "MeasurementUnitsCodeSequence is required in MeasuredValueSequence",
734 "SR-NUM-ERR-003"
735 });
736 }
737 }
738}

References kcenon::pacs::services::validation::error, kcenon::pacs::services::validation::sr_tags::measured_value_sequence, kcenon::pacs::services::validation::sr_tags::measurement_units_code_sequence, and kcenon::pacs::services::validation::sr_tags::numeric_value.

Referenced by validate_content_item().

Here is the caller graph for this function:

◆ validate_patient_module()

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

Definition at line 350 of file sr_iod_validator.cpp.

352 {
353
354 if (options_.check_type2) {
355 check_type2_attribute(dataset, tags::patient_name, "PatientName", findings);
356 check_type2_attribute(dataset, tags::patient_id, "PatientID", findings);
357 check_type2_attribute(dataset, tags::patient_birth_date, "PatientBirthDate", findings);
358 check_type2_attribute(dataset, tags::patient_sex, "PatientSex", findings);
359 }
360}
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::sr_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_basic_text_sr(), validate_comprehensive_sr(), validate_enhanced_sr(), and validate_key_object_selection().

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

◆ validate_references()

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

Validate referenced instances.

Checks that all referenced SOP instances are properly specified.

Parameters
datasetThe dataset to validate
Returns
Validation result for references

Definition at line 289 of file sr_iod_validator.cpp.

289 {
290 validation_result result;
291 result.is_valid = true;
292
293 validate_evidence_sequences(dataset, result.findings);
294
295 for (const auto& finding : result.findings) {
296 if (finding.severity == validation_severity::error) {
297 result.is_valid = false;
298 break;
299 }
300 }
301
302 return result;
303}

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

Here is the call graph for this function:

◆ validate_scoord3d_content_item()

void kcenon::pacs::services::validation::sr_iod_validator::validate_scoord3d_content_item ( const core::dicom_dataset & item,
std::vector< validation_finding > & findings ) const
private

Definition at line 801 of file sr_iod_validator.cpp.

803 {
804
805 if (!item.contains(sr_tags::graphic_type)) {
806 findings.push_back({
809 "GraphicType is required for SCOORD3D content item",
810 "SR-SCOORD3D-ERR-001"
811 });
812 }
813
814 if (!item.contains(sr_tags::graphic_data)) {
815 findings.push_back({
818 "GraphicData is required for SCOORD3D content item",
819 "SR-SCOORD3D-ERR-002"
820 });
821 }
822
824 findings.push_back({
827 "ReferencedFrameOfReferenceUID is required for SCOORD3D content item",
828 "SR-SCOORD3D-ERR-003"
829 });
830 }
831}

References kcenon::pacs::services::validation::error, kcenon::pacs::services::validation::sr_tags::graphic_data, kcenon::pacs::services::validation::sr_tags::graphic_type, and kcenon::pacs::services::validation::sr_tags::referenced_frame_of_reference_uid.

Referenced by validate_content_item().

Here is the caller graph for this function:

◆ validate_scoord_content_item()

void kcenon::pacs::services::validation::sr_iod_validator::validate_scoord_content_item ( const core::dicom_dataset & item,
std::vector< validation_finding > & findings ) const
private

Definition at line 778 of file sr_iod_validator.cpp.

780 {
781
782 if (!item.contains(sr_tags::graphic_type)) {
783 findings.push_back({
786 "GraphicType is required for SCOORD content item",
787 "SR-SCOORD-ERR-001"
788 });
789 }
790
791 if (!item.contains(sr_tags::graphic_data)) {
792 findings.push_back({
795 "GraphicData is required for SCOORD content item",
796 "SR-SCOORD-ERR-002"
797 });
798 }
799}

References kcenon::pacs::services::validation::error, kcenon::pacs::services::validation::sr_tags::graphic_data, and kcenon::pacs::services::validation::sr_tags::graphic_type.

Referenced by validate_content_item().

Here is the caller graph for this function:

◆ validate_sop_common_module()

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

Definition at line 476 of file sr_iod_validator.cpp.

478 {
479
480 if (options_.check_type1) {
481 check_type1_attribute(dataset, tags::sop_class_uid, "SOPClassUID", findings);
482 check_type1_attribute(dataset, tags::sop_instance_uid, "SOPInstanceUID", findings);
483 }
484
485 // Validate SOP Class UID is an SR storage class
486 if (dataset.contains(tags::sop_class_uid)) {
487 auto sop_class = dataset.get_string(tags::sop_class_uid);
488 if (!sop_classes::is_sr_storage_sop_class(sop_class)) {
489 findings.push_back({
492 "SOPClassUID is not a recognized SR Storage SOP Class: " + sop_class,
493 "SR-ERR-001"
494 });
495 }
496 }
497}

References kcenon::pacs::services::validation::sr_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_sr_storage_sop_class(), options_, kcenon::pacs::core::tags::sop_class_uid, and kcenon::pacs::core::tags::sop_instance_uid.

Referenced by validate_basic_text_sr(), validate_comprehensive_sr(), validate_enhanced_sr(), and validate_key_object_selection().

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

◆ validate_sr_document_content_module()

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

Definition at line 439 of file sr_iod_validator.cpp.

441 {
442
443 // Root content item attributes
444 if (options_.check_type1) {
445 check_type1_attribute(dataset, sr_tags::value_type, "ValueType", findings);
446 check_type1_attribute(dataset, sr_tags::concept_name_code_sequence, "ConceptNameCodeSequence", findings);
447 }
448
449 // Validate root value type
452 if (value_type != "CONTAINER") {
453 findings.push_back({
456 "Root content item ValueType must be CONTAINER, found: " + value_type,
457 "SR-CONTENT-ERR-001"
458 });
459 }
460 }
461
462 // Validate Concept Name Code Sequence
464 const auto* concept_elem = dataset.get(sr_tags::concept_name_code_sequence);
465 if (concept_elem && concept_elem->is_sequence() && !concept_elem->sequence_items().empty()) {
466 validate_coded_entry(concept_elem->sequence_items()[0], "Root Concept Name", findings);
467 }
468 }
469
470 // Validate content sequence
472 validate_content_sequence(dataset, findings);
473 }
474}
void validate_coded_entry(const core::dicom_dataset &coded_entry, std::string_view context, std::vector< validation_finding > &findings) const
bool validate_coded_entries
Validate coded entries (concept name codes, etc.)
bool validate_value_types
Validate content item value types.

References kcenon::pacs::services::validation::sr_validation_options::check_type1, check_type1_attribute(), kcenon::pacs::services::validation::sr_tags::concept_name_code_sequence, kcenon::pacs::core::dicom_dataset::contains(), kcenon::pacs::services::validation::error, kcenon::pacs::core::dicom_dataset::get(), kcenon::pacs::core::dicom_dataset::get_string(), options_, kcenon::pacs::services::validation::sr_validation_options::validate_coded_entries, validate_coded_entry(), validate_content_sequence(), kcenon::pacs::services::validation::sr_validation_options::validate_content_sequence, kcenon::pacs::services::validation::sr_validation_options::validate_value_types, and kcenon::pacs::services::validation::sr_tags::value_type.

Referenced by validate_basic_text_sr(), validate_comprehensive_sr(), validate_enhanced_sr(), and validate_key_object_selection().

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

◆ validate_sr_document_general_module()

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

Definition at line 404 of file sr_iod_validator.cpp.

406 {
407
408 if (options_.check_type1) {
409 check_type1_attribute(dataset, sr_tags::instance_number, "InstanceNumber", findings);
410 check_type1_attribute(dataset, sr_tags::completion_flag, "CompletionFlag", findings);
411 check_type1_attribute(dataset, sr_tags::verification_flag, "VerificationFlag", findings);
412 }
413
414 if (options_.check_type2) {
415 check_type2_attribute(dataset, sr_tags::content_date, "ContentDate", findings);
416 check_type2_attribute(dataset, sr_tags::content_time, "ContentTime", findings);
417 }
418
419 // Validate flag values
421 check_completion_flag(dataset, findings);
422 check_verification_flag(dataset, findings);
423 }
424
425 // VerifyingObserverSequence is Type 1C - required if VerificationFlag is VERIFIED
427 auto flag = dataset.get_string(sr_tags::verification_flag);
428 if (flag == "VERIFIED" && !dataset.contains(sr_tags::verifying_observer_sequence)) {
429 findings.push_back({
432 "VerifyingObserverSequence is required when VerificationFlag is VERIFIED",
433 "SR-DOC-ERR-001"
434 });
435 }
436 }
437}
void check_verification_flag(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void check_completion_flag(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
bool check_conditional
Check Type 1C/2C (conditionally required) attributes.
bool validate_document_status
Validate completion and verification flags.

References check_completion_flag(), kcenon::pacs::services::validation::sr_validation_options::check_conditional, kcenon::pacs::services::validation::sr_validation_options::check_type1, check_type1_attribute(), kcenon::pacs::services::validation::sr_validation_options::check_type2, check_type2_attribute(), check_verification_flag(), kcenon::pacs::services::validation::sr_tags::completion_flag, kcenon::pacs::core::dicom_dataset::contains(), kcenon::pacs::services::validation::sr_tags::content_date, kcenon::pacs::services::validation::sr_tags::content_time, kcenon::pacs::services::validation::error, kcenon::pacs::core::dicom_dataset::get_string(), kcenon::pacs::services::validation::sr_tags::instance_number, options_, kcenon::pacs::services::validation::sr_validation_options::validate_document_status, kcenon::pacs::services::validation::sr_tags::verification_flag, and kcenon::pacs::services::validation::sr_tags::verifying_observer_sequence.

Referenced by validate_basic_text_sr(), validate_comprehensive_sr(), validate_enhanced_sr(), and validate_key_object_selection().

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

◆ validate_sr_document_series_module()

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

Definition at line 379 of file sr_iod_validator.cpp.

381 {
382
383 if (options_.check_type1) {
384 check_type1_attribute(dataset, tags::modality, "Modality", findings);
385 check_type1_attribute(dataset, tags::series_instance_uid, "SeriesInstanceUID", findings);
386 check_modality(dataset, findings);
387 }
388
389 if (options_.check_type2) {
390 check_type2_attribute(dataset, tags::series_number, "SeriesNumber", findings);
391 }
392}
void check_modality(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
constexpr dicom_tag series_number
Series Number.

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

Referenced by validate_basic_text_sr(), validate_comprehensive_sr(), validate_enhanced_sr(), and validate_key_object_selection().

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

◆ validate_text_content_item()

void kcenon::pacs::services::validation::sr_iod_validator::validate_text_content_item ( const core::dicom_dataset & item,
std::vector< validation_finding > & findings ) const
private

Definition at line 674 of file sr_iod_validator.cpp.

676 {
677
678 if (!item.contains(sr_tags::text_value)) {
679 findings.push_back({
682 "TextValue is required for TEXT content item",
683 "SR-TEXT-ERR-001"
684 });
685 }
686}

References kcenon::pacs::services::validation::error, and kcenon::pacs::services::validation::sr_tags::text_value.

Referenced by validate_content_item().

Here is the caller graph for this function:

Member Data Documentation

◆ options_


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