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

#include <pet_iod_validator.h>

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

Public Member Functions

 pet_iod_validator ()=default
 Construct validator with default options.
 
 pet_iod_validator (const pet_validation_options &options)
 Construct validator with custom options.
 
validation_result validate (const core::dicom_dataset &dataset) const
 Validate a DICOM dataset against PET IOD.
 
bool quick_check (const core::dicom_dataset &dataset) const
 Quick check if dataset has minimum required attributes.
 
const pet_validation_optionsoptions () const noexcept
 Get the validation options.
 
void set_options (const pet_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_pet_series_module (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 
void validate_frame_of_reference_module (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 
void validate_pet_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_image_plane_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_radiopharmaceutical_info (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 
void validate_suv_parameters (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 
void validate_reconstruction_info (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 
void validate_corrections (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_pixel_data_consistency (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 

Private Attributes

pet_validation_options options_
 

Detailed Description

Definition at line 112 of file pet_iod_validator.h.

Constructor & Destructor Documentation

◆ pet_iod_validator() [1/2]

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

◆ pet_iod_validator() [2/2]

kcenon::pacs::services::validation::pet_iod_validator::pet_iod_validator ( const pet_validation_options & options)
explicit

Construct validator with custom options.

Parameters
optionsValidation options

Definition at line 61 of file pet_iod_validator.cpp.

Member Function Documentation

◆ check_modality()

void kcenon::pacs::services::validation::pet_iod_validator::check_modality ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/services/validation/pet_iod_validator.h.

Definition at line 550 of file pet_iod_validator.cpp.

552 {
553
554 if (!dataset.contains(tags::modality)) {
555 return; // Already reported as Type 1 missing
556 }
557
558 auto modality = dataset.get_string(tags::modality);
559 if (modality != "PT") {
560 findings.push_back({
563 "Modality must be 'PT' for PET images, found: " + modality,
564 "PT-ERR-003"
565 });
566 }
567}
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::pet_iod_validator::check_pixel_data_consistency ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/services/validation/pet_iod_validator.h.

Definition at line 569 of file pet_iod_validator.cpp.

571 {
572
573 // Check BitsStored <= BitsAllocated
574 auto bits_allocated = dataset.get_numeric<uint16_t>(tags::bits_allocated);
575 auto bits_stored = dataset.get_numeric<uint16_t>(tags::bits_stored);
576 auto high_bit = dataset.get_numeric<uint16_t>(tags::high_bit);
577
578 if (bits_allocated && bits_stored) {
579 if (*bits_stored > *bits_allocated) {
580 findings.push_back({
583 "BitsStored (" + std::to_string(*bits_stored) +
584 ") exceeds BitsAllocated (" + std::to_string(*bits_allocated) + ")",
585 "PT-ERR-004"
586 });
587 }
588 }
589
590 // Check HighBit == BitsStored - 1
591 if (bits_stored && high_bit) {
592 if (*high_bit != *bits_stored - 1) {
593 findings.push_back({
596 "HighBit (" + std::to_string(*high_bit) +
597 ") should typically be BitsStored - 1 (" +
598 std::to_string(*bits_stored - 1) + ")",
599 "PT-WARN-005"
600 });
601 }
602 }
603
604 // Check photometric interpretation is valid for PET
605 if (dataset.contains(tags::photometric_interpretation)) {
606 auto photometric = dataset.get_string(tags::photometric_interpretation);
607 if (!sop_classes::is_valid_pet_photometric(photometric)) {
608 findings.push_back({
611 "Unusual photometric interpretation for PET: " + photometric +
612 " (expected MONOCHROME2)",
613 "PT-WARN-006"
614 });
615 }
616 }
617
618 // PET images should be grayscale (SamplesPerPixel = 1)
619 auto samples = dataset.get_numeric<uint16_t>(tags::samples_per_pixel);
620 if (samples && *samples != 1) {
621 findings.push_back({
624 "PET images should have SamplesPerPixel = 1, found: " +
625 std::to_string(*samples),
626 "PT-WARN-007"
627 });
628 }
629}
constexpr dicom_tag high_bit
High Bit.
constexpr dicom_tag bits_allocated
Bits Allocated.
constexpr dicom_tag bits_stored
Bits Stored.
constexpr dicom_tag samples_per_pixel
Samples per Pixel.
constexpr dicom_tag photometric_interpretation
Photometric Interpretation.
bool is_valid_pet_photometric(std::string_view value) noexcept
Check if photometric interpretation is valid for PET.
@ warning
Non-critical - IOD may have issues.

References kcenon::pacs::core::tags::bits_allocated, kcenon::pacs::core::tags::bits_stored, 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::high_bit, kcenon::pacs::services::sop_classes::is_valid_pet_photometric(), kcenon::pacs::core::tags::photometric_interpretation, kcenon::pacs::core::tags::samples_per_pixel, 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_type1_attribute()

void kcenon::pacs::services::validation::pet_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
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/services/validation/pet_iod_validator.h.

Definition at line 503 of file pet_iod_validator.cpp.

507 {
508
509 if (!dataset.contains(tag)) {
510 findings.push_back({
512 tag,
513 std::string("Type 1 attribute missing: ") + std::string(name) +
514 " (" + tag.to_string() + ")",
515 "PT-TYPE1-MISSING"
516 });
517 } else {
518 // Type 1 must have a value (cannot be empty)
519 auto value = dataset.get_string(tag);
520 if (value.empty()) {
521 findings.push_back({
523 tag,
524 std::string("Type 1 attribute has empty value: ") +
525 std::string(name) + " (" + tag.to_string() + ")",
526 "PT-TYPE1-EMPTY"
527 });
528 }
529 }
530}
std::string_view name

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

Referenced by validate_frame_of_reference_module(), validate_general_series_module(), validate_general_study_module(), validate_image_pixel_module(), validate_image_plane_module(), validate_pet_image_module(), validate_pet_series_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::pet_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
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/services/validation/pet_iod_validator.h.

Definition at line 532 of file pet_iod_validator.cpp.

536 {
537
538 // Type 2 must be present but can be empty
539 if (!dataset.contains(tag)) {
540 findings.push_back({
542 tag,
543 std::string("Type 2 attribute missing: ") + std::string(name) +
544 " (" + tag.to_string() + ")",
545 "PT-TYPE2-MISSING"
546 });
547 }
548}

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

Referenced by validate_frame_of_reference_module(), validate_general_series_module(), validate_general_study_module(), validate_image_plane_module(), validate_patient_module(), and validate_radiopharmaceutical_info().

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

◆ options()

const pet_validation_options & kcenon::pacs::services::validation::pet_iod_validator::options ( ) const
nodiscardnoexcept

Get the validation options.

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/services/validation/pet_iod_validator.h.

Definition at line 146 of file pet_iod_validator.cpp.

146 {
147 return options_;
148}

References options_.

Referenced by set_options().

Here is the caller graph for this function:

◆ quick_check()

bool kcenon::pacs::services::validation::pet_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
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/services/validation/pet_iod_validator.h.

Definition at line 111 of file pet_iod_validator.cpp.

111 {
112 // Check only Type 1 required attributes for quick validation
113
114 // General Study Module Type 1
115 if (!dataset.contains(tags::study_instance_uid)) return false;
116
117 // General Series Module Type 1
118 if (!dataset.contains(tags::modality)) return false;
119 if (!dataset.contains(tags::series_instance_uid)) return false;
120
121 // Check modality is PT
122 auto modality = dataset.get_string(tags::modality);
123 if (modality != "PT") return false;
124
125 // Frame of Reference Module Type 1
126 if (!dataset.contains(pet_tags::frame_of_reference_uid)) return false;
127
128 // Image Pixel Module Type 1
129 if (!dataset.contains(tags::samples_per_pixel)) return false;
130 if (!dataset.contains(tags::photometric_interpretation)) return false;
131 if (!dataset.contains(tags::rows)) return false;
132 if (!dataset.contains(tags::columns)) return false;
133 if (!dataset.contains(tags::bits_allocated)) return false;
134 if (!dataset.contains(tags::bits_stored)) return false;
135 if (!dataset.contains(tags::high_bit)) return false;
136 if (!dataset.contains(tags::pixel_representation)) return false;
137 if (!dataset.contains(tags::pixel_data)) return false;
138
139 // SOP Common Module Type 1
140 if (!dataset.contains(tags::sop_class_uid)) return false;
141 if (!dataset.contains(tags::sop_instance_uid)) return false;
142
143 return true;
144}
constexpr dicom_tag rows
Rows.
constexpr dicom_tag columns
Columns.
constexpr dicom_tag sop_instance_uid
SOP Instance UID.
constexpr dicom_tag pixel_data
Pixel Data.
constexpr dicom_tag pixel_representation
Pixel Representation.
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.

References kcenon::pacs::core::tags::bits_allocated, kcenon::pacs::core::tags::bits_stored, kcenon::pacs::core::tags::columns, kcenon::pacs::core::dicom_dataset::contains(), kcenon::pacs::services::validation::pet_tags::frame_of_reference_uid, kcenon::pacs::core::dicom_dataset::get_string(), kcenon::pacs::core::tags::high_bit, kcenon::pacs::core::tags::modality, kcenon::pacs::core::tags::photometric_interpretation, kcenon::pacs::core::tags::pixel_data, kcenon::pacs::core::tags::pixel_representation, kcenon::pacs::core::tags::rows, kcenon::pacs::core::tags::samples_per_pixel, 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_pet_dataset().

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

◆ set_options()

void kcenon::pacs::services::validation::pet_iod_validator::set_options ( const pet_validation_options & options)

Set validation options.

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/services/validation/pet_iod_validator.h.

Definition at line 150 of file pet_iod_validator.cpp.

150 {
152}
const pet_validation_options & options() const noexcept
Get the validation options.

References options(), and options_.

Here is the call graph for this function:

◆ validate()

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

Validate a DICOM dataset against PET IOD.

Parameters
datasetThe dataset to validate
Returns
Validation result with all findings
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/services/validation/pet_iod_validator.h.

Definition at line 64 of file pet_iod_validator.cpp.

64 {
65 validation_result result;
66 result.is_valid = true;
67
68 // Validate mandatory modules
70 validate_patient_module(dataset, result.findings);
71 validate_general_study_module(dataset, result.findings);
72 validate_general_series_module(dataset, result.findings);
73 validate_pet_series_module(dataset, result.findings);
74 validate_frame_of_reference_module(dataset, result.findings);
75 validate_pet_image_module(dataset, result.findings);
76 validate_sop_common_module(dataset, result.findings);
77 }
78
80 validate_image_pixel_module(dataset, result.findings);
81 validate_image_plane_module(dataset, result.findings);
82 }
83
84 // PET-specific validation
87 validate_radiopharmaceutical_info(dataset, result.findings);
88 }
89 validate_suv_parameters(dataset, result.findings);
90 validate_reconstruction_info(dataset, result.findings);
92 validate_corrections(dataset, result.findings);
93 }
94 }
95
96 // Check for errors
97 for (const auto& finding : result.findings) {
98 if (finding.severity == validation_severity::error) {
99 result.is_valid = false;
100 break;
101 }
102 if (options_.strict_mode && finding.severity == validation_severity::warning) {
103 result.is_valid = false;
104 break;
105 }
106 }
107
108 return result;
109}
void validate_general_series_module(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void validate_image_plane_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_pet_series_module(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void validate_corrections(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void validate_frame_of_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 validate_reconstruction_info(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_radiopharmaceutical_info(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void validate_suv_parameters(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void validate_pet_image_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
bool validate_corrections
Validate attenuation and scatter correction.
bool check_type1
Check Type 1 (required) attributes.
bool validate_pet_specific
Validate PET-specific attributes (SUV, reconstruction, etc.)
bool strict_mode
Strict mode - treat warnings as errors.
bool check_type2
Check Type 2 (required, can be empty) attributes.
bool validate_pixel_data
Validate pixel data consistency (rows, columns, bits)
bool validate_radiopharmaceutical
Validate radiopharmaceutical information.

References kcenon::pacs::services::validation::pet_validation_options::check_type1, kcenon::pacs::services::validation::pet_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::pet_validation_options::strict_mode, validate_corrections(), kcenon::pacs::services::validation::pet_validation_options::validate_corrections, validate_frame_of_reference_module(), validate_general_series_module(), validate_general_study_module(), validate_image_pixel_module(), validate_image_plane_module(), validate_patient_module(), validate_pet_image_module(), validate_pet_series_module(), kcenon::pacs::services::validation::pet_validation_options::validate_pet_specific, kcenon::pacs::services::validation::pet_validation_options::validate_pixel_data, kcenon::pacs::services::validation::pet_validation_options::validate_radiopharmaceutical, validate_radiopharmaceutical_info(), validate_reconstruction_info(), validate_sop_common_module(), validate_suv_parameters(), and kcenon::pacs::services::validation::warning.

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

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

◆ validate_corrections()

void kcenon::pacs::services::validation::pet_iod_validator::validate_corrections ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/services/validation/pet_iod_validator.h.

Definition at line 468 of file pet_iod_validator.cpp.

470 {
471
472 // Attenuation Correction Method is Type 3 but important
473 if (!dataset.contains(pet_tags::attenuation_correction_method)) {
474 findings.push_back({
477 "AttenuationCorrectionMethod not specified",
478 "PT-INFO-005"
479 });
480 }
481
482 // For quantitative PET, corrections are critical
483 if (dataset.contains(pet_tags::units)) {
484 auto units = dataset.get_string(pet_tags::units);
485 if (units == "BQML" || units == "GML") {
486 // Randoms correction
487 if (!dataset.contains(pet_tags::randoms_correction_method)) {
488 findings.push_back({
491 "RandomsCorrectionMethod recommended for quantitative PET",
492 "PT-INFO-006"
493 });
494 }
495 }
496 }
497}
@ info
Informational - suggestion for improvement.

References kcenon::pacs::services::validation::pet_tags::attenuation_correction_method, kcenon::pacs::core::dicom_dataset::contains(), kcenon::pacs::core::dicom_dataset::get_string(), kcenon::pacs::services::validation::info, kcenon::pacs::services::validation::pet_tags::randoms_correction_method, and kcenon::pacs::services::validation::pet_tags::units.

Referenced by validate().

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

◆ validate_frame_of_reference_module()

void kcenon::pacs::services::validation::pet_iod_validator::validate_frame_of_reference_module ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/services/validation/pet_iod_validator.h.

Definition at line 250 of file pet_iod_validator.cpp.

252 {
253
254 // Type 1
255 if (options_.check_type1) {
257 "FrameOfReferenceUID", findings);
258 }
259
260 // Type 2
261 if (options_.check_type2) {
263 "PositionReferenceIndicator", findings);
264 }
265}
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_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::pet_validation_options::check_type1, check_type1_attribute(), kcenon::pacs::services::validation::pet_validation_options::check_type2, check_type2_attribute(), kcenon::pacs::services::validation::pet_tags::frame_of_reference_uid, options_, and kcenon::pacs::services::validation::pet_tags::position_reference_indicator.

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::pet_iod_validator::validate_general_series_module ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/services/validation/pet_iod_validator.h.

Definition at line 190 of file pet_iod_validator.cpp.

192 {
193
194 // Type 1
195 if (options_.check_type1) {
196 check_type1_attribute(dataset, tags::modality, "Modality", findings);
197 check_type1_attribute(dataset, tags::series_instance_uid, "SeriesInstanceUID", findings);
198
199 // Special check: Modality must be "PT"
200 check_modality(dataset, findings);
201 }
202
203 // Type 2
204 if (options_.check_type2) {
205 check_type2_attribute(dataset, tags::series_number, "SeriesNumber", findings);
206 }
207}
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::pet_validation_options::check_type1, check_type1_attribute(), kcenon::pacs::services::validation::pet_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().

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::pet_iod_validator::validate_general_study_module ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/services/validation/pet_iod_validator.h.

Definition at line 171 of file pet_iod_validator.cpp.

173 {
174
175 // Type 1
176 if (options_.check_type1) {
177 check_type1_attribute(dataset, tags::study_instance_uid, "StudyInstanceUID", findings);
178 }
179
180 // Type 2
181 if (options_.check_type2) {
182 check_type2_attribute(dataset, tags::study_date, "StudyDate", findings);
183 check_type2_attribute(dataset, tags::study_time, "StudyTime", findings);
184 check_type2_attribute(dataset, tags::referring_physician_name, "ReferringPhysicianName", findings);
185 check_type2_attribute(dataset, tags::study_id, "StudyID", findings);
186 check_type2_attribute(dataset, tags::accession_number, "AccessionNumber", findings);
187 }
188}
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::pet_validation_options::check_type1, check_type1_attribute(), kcenon::pacs::services::validation::pet_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::pet_iod_validator::validate_image_pixel_module ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/services/validation/pet_iod_validator.h.

Definition at line 310 of file pet_iod_validator.cpp.

312 {
313
314 // Type 1 attributes
315 if (options_.check_type1) {
316 check_type1_attribute(dataset, tags::samples_per_pixel, "SamplesPerPixel", findings);
318 "PhotometricInterpretation", findings);
319 check_type1_attribute(dataset, tags::rows, "Rows", findings);
320 check_type1_attribute(dataset, tags::columns, "Columns", findings);
321 check_type1_attribute(dataset, tags::bits_allocated, "BitsAllocated", findings);
322 check_type1_attribute(dataset, tags::bits_stored, "BitsStored", findings);
323 check_type1_attribute(dataset, tags::high_bit, "HighBit", findings);
324 check_type1_attribute(dataset, tags::pixel_representation, "PixelRepresentation", findings);
325 check_type1_attribute(dataset, tags::pixel_data, "PixelData", findings);
326 }
327
328 // Validate pixel data consistency
330 check_pixel_data_consistency(dataset, findings);
331 }
332}
void check_pixel_data_consistency(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const

References kcenon::pacs::core::tags::bits_allocated, kcenon::pacs::core::tags::bits_stored, check_pixel_data_consistency(), kcenon::pacs::services::validation::pet_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_data, kcenon::pacs::core::tags::pixel_representation, kcenon::pacs::core::tags::rows, kcenon::pacs::core::tags::samples_per_pixel, and kcenon::pacs::services::validation::pet_validation_options::validate_pixel_data.

Referenced by validate().

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

◆ validate_image_plane_module()

void kcenon::pacs::services::validation::pet_iod_validator::validate_image_plane_module ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/services/validation/pet_iod_validator.h.

Definition at line 334 of file pet_iod_validator.cpp.

336 {
337
338 // Type 1
339 if (options_.check_type1) {
340 check_type1_attribute(dataset, pet_tags::pixel_spacing, "PixelSpacing", findings);
342 "ImageOrientationPatient", findings);
344 "ImagePositionPatient", findings);
345 }
346
347 // Type 2
348 if (options_.check_type2) {
349 check_type2_attribute(dataset, pet_tags::slice_thickness, "SliceThickness", findings);
350 }
351}

References kcenon::pacs::services::validation::pet_validation_options::check_type1, check_type1_attribute(), kcenon::pacs::services::validation::pet_validation_options::check_type2, check_type2_attribute(), kcenon::pacs::services::validation::pet_tags::image_orientation_patient, kcenon::pacs::services::validation::pet_tags::image_position_patient, options_, kcenon::pacs::services::validation::pet_tags::pixel_spacing, and kcenon::pacs::services::validation::pet_tags::slice_thickness.

Referenced by validate().

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

◆ validate_patient_module()

void kcenon::pacs::services::validation::pet_iod_validator::validate_patient_module ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/services/validation/pet_iod_validator.h.

Definition at line 158 of file pet_iod_validator.cpp.

160 {
161
162 // Patient Module - All attributes are Type 2
163 if (options_.check_type2) {
164 check_type2_attribute(dataset, tags::patient_name, "PatientName", findings);
165 check_type2_attribute(dataset, tags::patient_id, "PatientID", findings);
166 check_type2_attribute(dataset, tags::patient_birth_date, "PatientBirthDate", findings);
167 check_type2_attribute(dataset, tags::patient_sex, "PatientSex", findings);
168 }
169}
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::pet_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_pet_image_module()

void kcenon::pacs::services::validation::pet_iod_validator::validate_pet_image_module ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/services/validation/pet_iod_validator.h.

Definition at line 267 of file pet_iod_validator.cpp.

269 {
270
271 // Type 1
272 if (options_.check_type1) {
273 check_type1_attribute(dataset, pet_tags::image_type, "ImageType", findings);
275 "FrameReferenceTime", findings);
276 }
277
278 // Type 1C - Decay Correction (required if Units = BQML)
280 if (dataset.contains(pet_tags::units)) {
281 auto units = dataset.get_string(pet_tags::units);
282 if (units == "BQML") {
283 if (!dataset.contains(pet_tags::decay_correction)) {
284 findings.push_back({
287 "DecayCorrection is required when Units = BQML",
288 "PT-ERR-001"
289 });
290 }
291 }
292 }
293 }
294
295 // Validate DecayCorrection value
296 if (dataset.contains(pet_tags::decay_correction)) {
297 auto decay = dataset.get_string(pet_tags::decay_correction);
298 if (decay != "NONE" && decay != "START" && decay != "ADMIN") {
299 findings.push_back({
302 "Invalid DecayCorrection value: " + decay +
303 " (expected NONE, START, or ADMIN)",
304 "PT-WARN-002"
305 });
306 }
307 }
308}
bool check_conditional
Check Type 1C/2C (conditionally required) attributes.

References kcenon::pacs::services::validation::pet_validation_options::check_conditional, kcenon::pacs::services::validation::pet_validation_options::check_type1, check_type1_attribute(), kcenon::pacs::core::dicom_dataset::contains(), kcenon::pacs::services::validation::pet_tags::decay_correction, kcenon::pacs::services::validation::error, kcenon::pacs::services::validation::pet_tags::frame_reference_time, kcenon::pacs::core::dicom_dataset::get_string(), kcenon::pacs::services::validation::pet_tags::image_type, options_, kcenon::pacs::services::validation::pet_tags::units, 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_pet_series_module()

void kcenon::pacs::services::validation::pet_iod_validator::validate_pet_series_module ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/services/validation/pet_iod_validator.h.

Definition at line 209 of file pet_iod_validator.cpp.

211 {
212
213 // PET Series Module Type 1 attributes
214 if (options_.check_type1) {
215 check_type1_attribute(dataset, pet_tags::series_type, "SeriesType", findings);
216 check_type1_attribute(dataset, pet_tags::units, "Units", findings);
217 check_type1_attribute(dataset, pet_tags::counts_source, "CountsSource", findings);
218 }
219
220 // Validate Units value
221 if (dataset.contains(pet_tags::units)) {
222 auto units = dataset.get_string(pet_tags::units);
223 if (units != "CNTS" && units != "BQML" && units != "GML" &&
224 units != "PROPCNTS" && units != "NONE") {
225 findings.push_back({
228 "Unusual Units value for PET: " + units +
229 " (expected CNTS, BQML, or GML)",
230 "PT-WARN-001"
231 });
232 }
233 }
234
235 // Validate SeriesType
236 if (dataset.contains(pet_tags::series_type)) {
237 auto series_type = dataset.get_string(pet_tags::series_type);
238 // SeriesType should be like "STATIC\IMAGE" or "WHOLE BODY\IMAGE"
239 if (series_type.find('\\') == std::string::npos) {
240 findings.push_back({
243 "SeriesType should contain backslash separator (e.g., STATIC\\IMAGE)",
244 "PT-INFO-001"
245 });
246 }
247 }
248}

References kcenon::pacs::services::validation::pet_validation_options::check_type1, check_type1_attribute(), kcenon::pacs::core::dicom_dataset::contains(), kcenon::pacs::services::validation::pet_tags::counts_source, kcenon::pacs::core::dicom_dataset::get_string(), kcenon::pacs::services::validation::info, options_, kcenon::pacs::services::validation::pet_tags::series_type, kcenon::pacs::services::validation::pet_tags::units, 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_radiopharmaceutical_info()

void kcenon::pacs::services::validation::pet_iod_validator::validate_radiopharmaceutical_info ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/services/validation/pet_iod_validator.h.

Definition at line 381 of file pet_iod_validator.cpp.

383 {
384
385 // Radiopharmaceutical Information Sequence is Type 2
386 if (options_.check_type2) {
388 "RadiopharmaceuticalInformationSequence", findings);
389 }
390
391 // If sequence is present, validate its contents
392 if (dataset.contains(pet_tags::radiopharmaceutical_info_sequence)) {
393 // For quantitative PET (BQML), dose and half-life are critical
394 if (dataset.contains(pet_tags::units)) {
395 auto units = dataset.get_string(pet_tags::units);
396 if (units == "BQML" || units == "GML") {
397 // Check for required dose information
398 if (!dataset.contains(pet_tags::radionuclide_total_dose)) {
399 findings.push_back({
402 "RadionuclideTotalDose recommended for quantitative PET",
403 "PT-WARN-003"
404 });
405 }
406 if (!dataset.contains(pet_tags::radionuclide_half_life)) {
407 findings.push_back({
410 "RadionuclideHalfLife recommended for quantitative PET",
411 "PT-WARN-004"
412 });
413 }
414 }
415 }
416 }
417}

References kcenon::pacs::services::validation::pet_validation_options::check_type2, check_type2_attribute(), kcenon::pacs::core::dicom_dataset::contains(), kcenon::pacs::core::dicom_dataset::get_string(), options_, kcenon::pacs::services::validation::pet_tags::radionuclide_half_life, kcenon::pacs::services::validation::pet_tags::radionuclide_total_dose, kcenon::pacs::services::validation::pet_tags::radiopharmaceutical_info_sequence, kcenon::pacs::services::validation::pet_tags::units, 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_reconstruction_info()

void kcenon::pacs::services::validation::pet_iod_validator::validate_reconstruction_info ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/services/validation/pet_iod_validator.h.

Definition at line 453 of file pet_iod_validator.cpp.

455 {
456
457 // Reconstruction Method is informational but important for interpretation
458 if (!dataset.contains(pet_tags::reconstruction_method)) {
459 findings.push_back({
462 "ReconstructionMethod not specified - helps with interpretation",
463 "PT-INFO-004"
464 });
465 }
466}

References kcenon::pacs::core::dicom_dataset::contains(), kcenon::pacs::services::validation::info, and kcenon::pacs::services::validation::pet_tags::reconstruction_method.

Referenced by validate().

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::pet_iod_validator::validate_sop_common_module ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/services/validation/pet_iod_validator.h.

Definition at line 353 of file pet_iod_validator.cpp.

355 {
356
357 // Type 1
358 if (options_.check_type1) {
359 check_type1_attribute(dataset, tags::sop_class_uid, "SOPClassUID", findings);
360 check_type1_attribute(dataset, tags::sop_instance_uid, "SOPInstanceUID", findings);
361 }
362
363 // Validate SOP Class UID is a PET storage class
364 if (dataset.contains(tags::sop_class_uid)) {
365 auto sop_class = dataset.get_string(tags::sop_class_uid);
367 findings.push_back({
370 "SOPClassUID is not a recognized PET Storage SOP Class: " + sop_class,
371 "PT-ERR-002"
372 });
373 }
374 }
375}
bool is_pet_storage_sop_class(std::string_view uid) noexcept
Check if a SOP Class UID is a PET Storage SOP Class.

References kcenon::pacs::services::validation::pet_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_pet_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:

◆ validate_suv_parameters()

void kcenon::pacs::services::validation::pet_iod_validator::validate_suv_parameters ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/services/validation/pet_iod_validator.h.

Definition at line 419 of file pet_iod_validator.cpp.

421 {
422
423 // SUV calculation requires specific parameters
424 if (dataset.contains(pet_tags::units)) {
425 auto units = dataset.get_string(pet_tags::units);
426
427 // For SUV calculation, rescale parameters are important
428 if (units == "BQML" || units == "GML") {
429 if (!dataset.contains(pet_tags::rescale_slope)) {
430 findings.push_back({
433 "RescaleSlope recommended for accurate SUV calculation",
434 "PT-INFO-002"
435 });
436 }
437 }
438
439 // Decay factor for quantitative analysis
440 if (units == "BQML") {
441 if (!dataset.contains(pet_tags::decay_factor)) {
442 findings.push_back({
445 "DecayFactor recommended for quantitative analysis",
446 "PT-INFO-003"
447 });
448 }
449 }
450 }
451}

References kcenon::pacs::core::dicom_dataset::contains(), kcenon::pacs::services::validation::pet_tags::decay_factor, kcenon::pacs::core::dicom_dataset::get_string(), kcenon::pacs::services::validation::info, kcenon::pacs::services::validation::pet_tags::rescale_slope, and kcenon::pacs::services::validation::pet_tags::units.

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: