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

Validator for VL Whole Slide Microscopy Image IODs. More...

#include <wsi_iod_validator.h>

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

Public Member Functions

 wsi_iod_validator ()=default
 Construct validator with default options.
 
 wsi_iod_validator (const wsi_validation_options &options)
 Construct validator with custom options.
 
validation_result validate (const core::dicom_dataset &dataset) const
 Validate a DICOM dataset against WSI IOD.
 
bool quick_check (const core::dicom_dataset &dataset) const
 Quick check if dataset has minimum required WSI attributes.
 
const wsi_validation_options & options () const noexcept
 Get the validation options.
 
void set_options (const wsi_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_wsi_image_module (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 
void validate_optical_path_module (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 
void validate_multiframe_dimension_module (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 
void validate_image_pixel_module (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 
void validate_specimen_module (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 
void validate_sop_common_module (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 
void check_type1_attribute (const core::dicom_dataset &dataset, core::dicom_tag tag, std::string_view name, std::vector< validation_finding > &findings) const
 
void check_type2_attribute (const core::dicom_dataset &dataset, core::dicom_tag tag, std::string_view name, std::vector< validation_finding > &findings) const
 
void check_modality (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 
void check_pixel_data_consistency (const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
 

Private Attributes

wsi_validation_options options_
 

Detailed Description

Validator for VL Whole Slide Microscopy Image IODs.

Validates DICOM datasets against the VL Whole Slide Microscopy Image IOD specification (PS3.3 Section A.32.8).

Validated Modules (PS3.3 Table A.32.8-1)

Mandatory Modules

  • Patient Module (M)
  • General Study Module (M)
  • General Series Module (M) — Modality = "SM"
  • Whole Slide Microscopy Image Module (M)
  • Optical Path Module (M)
  • Multi-frame Dimension Module (M)
  • Image Pixel Module (M)
  • SOP Common Module (M)

User Optional Modules

  • Specimen Module (U) — checked at info level
Example:
auto result = validator.validate(dataset);
if (!result.is_valid) {
for (const auto& finding : result.findings) {
std::cerr << finding.message << "\n";
}
}
Validator for VL Whole Slide Microscopy Image IODs.
validation_result validate(const core::dicom_dataset &dataset) const
Validate a DICOM dataset against WSI IOD.

Definition at line 146 of file wsi_iod_validator.h.

Constructor & Destructor Documentation

◆ wsi_iod_validator() [1/2]

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

Construct validator with default options.

◆ wsi_iod_validator() [2/2]

kcenon::pacs::services::validation::wsi_iod_validator::wsi_iod_validator ( const wsi_validation_options & options)
explicit

Construct validator with custom options.

Parameters
optionsValidation options

Definition at line 25 of file wsi_iod_validator.cpp.

26 : options_(options) {}
const wsi_validation_options & options() const noexcept
Get the validation options.

Member Function Documentation

◆ check_modality()

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

Definition at line 403 of file wsi_iod_validator.cpp.

405 {
406
407 if (!dataset.contains(tags::modality)) {
408 return; // Already reported as Type 1 missing
409 }
410
411 auto modality = dataset.get_string(tags::modality);
412 if (modality != "SM") {
413 findings.push_back(
415 "Modality must be 'SM' for WSI images, found: " + modality,
416 "WSI-ERR-003"});
417 }
418}
auto contains(dicom_tag tag) const noexcept -> bool
Check if the dataset contains an element with the given tag.
auto get_string(dicom_tag tag, std::string_view default_value="") const -> std::string
Get the string value of an element.
constexpr dicom_tag modality
Modality.

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

Referenced by validate_general_series_module().

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

◆ check_pixel_data_consistency()

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

Definition at line 420 of file wsi_iod_validator.cpp.

422 {
423
424 // Check BitsStored <= BitsAllocated
425 auto bits_allocated =
426 dataset.get_numeric<uint16_t>(tags::bits_allocated);
427 auto bits_stored = dataset.get_numeric<uint16_t>(tags::bits_stored);
428 auto high_bit = dataset.get_numeric<uint16_t>(tags::high_bit);
429
430 if (bits_allocated && bits_stored) {
431 if (*bits_stored > *bits_allocated) {
432 findings.push_back(
434 "BitsStored (" + std::to_string(*bits_stored) +
435 ") exceeds BitsAllocated (" +
436 std::to_string(*bits_allocated) + ")",
437 "WSI-ERR-004"});
438 }
439 }
440
441 // Check HighBit == BitsStored - 1
442 if (bits_stored && high_bit) {
443 if (*high_bit != *bits_stored - 1) {
444 findings.push_back(
446 "HighBit (" + std::to_string(*high_bit) +
447 ") should typically be BitsStored - 1 (" +
448 std::to_string(*bits_stored - 1) + ")",
449 "WSI-WARN-002"});
450 }
451 }
452
453 // Validate PhotometricInterpretation for WSI
455 auto photometric =
457 if (!sop_classes::is_valid_wsi_photometric(photometric)) {
458 findings.push_back(
461 "WSI images must use RGB, YBR_FULL_422, YBR_ICT, YBR_RCT, "
462 "or MONOCHROME2, found: " + photometric,
463 "WSI-ERR-005"});
464 }
465 }
466
467 // WSI SamplesPerPixel must be 1 (grayscale/fluorescence) or 3 (color)
468 auto samples = dataset.get_numeric<uint16_t>(tags::samples_per_pixel);
469 if (samples && *samples != 1 && *samples != 3) {
470 findings.push_back(
472 "WSI images require SamplesPerPixel of 1 or 3, found: " +
473 std::to_string(*samples),
474 "WSI-ERR-006"});
475 }
476
477 // WSI images must use unsigned pixel representation
478 auto pixel_rep =
479 dataset.get_numeric<uint16_t>(tags::pixel_representation);
480 if (pixel_rep && *pixel_rep != 0) {
481 findings.push_back(
483 "WSI images typically use unsigned pixel representation "
484 "(PixelRepresentation = 0)",
485 "WSI-WARN-003"});
486 }
487}
auto get_numeric(dicom_tag tag) const -> std::optional< T >
Get the numeric value of an element.
constexpr dicom_tag high_bit
High Bit.
constexpr dicom_tag bits_allocated
Bits Allocated.
constexpr dicom_tag bits_stored
Bits Stored.
constexpr dicom_tag pixel_representation
Pixel Representation.
constexpr dicom_tag samples_per_pixel
Samples per Pixel.
constexpr dicom_tag photometric_interpretation
Photometric Interpretation.
bool is_valid_wsi_photometric(std::string_view value) noexcept
Check if photometric interpretation is valid for WSI.
@ 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_wsi_photometric(), kcenon::pacs::core::tags::photometric_interpretation, kcenon::pacs::core::tags::pixel_representation, 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::wsi_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 366 of file wsi_iod_validator.cpp.

368 {
369
370 if (!dataset.contains(tag)) {
371 findings.push_back(
373 std::string("Type 1 attribute missing: ") + std::string(name) +
374 " (" + tag.to_string() + ")",
375 "WSI-TYPE1-MISSING"});
376 } else {
377 // Type 1 must have a value (cannot be empty)
378 auto value = dataset.get_string(tag);
379 if (value.empty()) {
380 findings.push_back(
382 std::string("Type 1 attribute has empty value: ") +
383 std::string(name) + " (" + tag.to_string() + ")",
384 "WSI-TYPE1-EMPTY"});
385 }
386 }
387}
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_string(), name, and kcenon::pacs::core::dicom_tag::to_string().

Referenced by validate_general_series_module(), validate_general_study_module(), validate_image_pixel_module(), validate_multiframe_dimension_module(), validate_optical_path_module(), validate_sop_common_module(), and validate_wsi_image_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::wsi_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 389 of file wsi_iod_validator.cpp.

391 {
392
393 // Type 2 must be present but can be empty
394 if (!dataset.contains(tag)) {
395 findings.push_back(
397 std::string("Type 2 attribute missing: ") + std::string(name) +
398 " (" + tag.to_string() + ")",
399 "WSI-TYPE2-MISSING"});
400 }
401}

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_series_module(), validate_general_study_module(), and validate_patient_module().

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

◆ options()

const wsi_validation_options & kcenon::pacs::services::validation::wsi_iod_validator::options ( ) const
nodiscardnoexcept

Get the validation options.

Definition at line 110 of file wsi_iod_validator.cpp.

110 {
111 return options_;
112}

References options_.

Referenced by set_options().

Here is the caller graph for this function:

◆ quick_check()

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

Quick check if dataset has minimum required WSI attributes.

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

Definition at line 75 of file wsi_iod_validator.cpp.

75 {
76 // General Study Module Type 1
77 if (!dataset.contains(tags::study_instance_uid)) return false;
78
79 // General Series Module Type 1
80 if (!dataset.contains(tags::modality)) return false;
81 if (!dataset.contains(tags::series_instance_uid)) return false;
82
83 // Check modality is SM
84 auto modality = dataset.get_string(tags::modality);
85 if (modality != "SM") return false;
86
87 // WSI Image Module Type 1
88 if (!dataset.contains(tags::image_type)) return false;
90 return false;
91 if (!dataset.contains(wsi_iod_tags::total_pixel_matrix_rows)) return false;
92
93 // Image Pixel Module Type 1
94 if (!dataset.contains(tags::samples_per_pixel)) return false;
95 if (!dataset.contains(tags::photometric_interpretation)) return false;
96 if (!dataset.contains(tags::rows)) return false;
97 if (!dataset.contains(tags::columns)) return false;
98 if (!dataset.contains(tags::bits_allocated)) return false;
99 if (!dataset.contains(tags::bits_stored)) return false;
100 if (!dataset.contains(tags::high_bit)) return false;
101 if (!dataset.contains(tags::pixel_representation)) return false;
102
103 // SOP Common Module Type 1
104 if (!dataset.contains(tags::sop_class_uid)) return false;
105 if (!dataset.contains(tags::sop_instance_uid)) return false;
106
107 return true;
108}
constexpr dicom_tag rows
Rows.
constexpr dicom_tag columns
Columns.
constexpr dicom_tag sop_instance_uid
SOP Instance UID.
constexpr dicom_tag image_type
Image Type.
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.
constexpr core::dicom_tag total_pixel_matrix_columns
Total Pixel Matrix Columns (0048,0006)
constexpr core::dicom_tag total_pixel_matrix_rows
Total Pixel Matrix Rows (0048,0007)

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::core::dicom_dataset::get_string(), kcenon::pacs::core::tags::high_bit, kcenon::pacs::core::tags::image_type, kcenon::pacs::core::tags::modality, kcenon::pacs::core::tags::photometric_interpretation, 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, kcenon::pacs::core::tags::study_instance_uid, kcenon::pacs::services::validation::wsi_iod_tags::total_pixel_matrix_columns, and kcenon::pacs::services::validation::wsi_iod_tags::total_pixel_matrix_rows.

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

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

◆ set_options()

void kcenon::pacs::services::validation::wsi_iod_validator::set_options ( const wsi_validation_options & options)

Set validation options.

Definition at line 114 of file wsi_iod_validator.cpp.

114 {
116}

References options(), and options_.

Here is the call graph for this function:

◆ validate()

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

Validate a DICOM dataset against WSI IOD.

Parameters
datasetThe dataset to validate
Returns
Validation result with all findings

Definition at line 28 of file wsi_iod_validator.cpp.

29 {
30 validation_result result;
31 result.is_valid = true;
32
33 // Validate mandatory modules (PS3.3 Table A.32.8-1)
35 validate_patient_module(dataset, result.findings);
36 validate_general_study_module(dataset, result.findings);
37 validate_general_series_module(dataset, result.findings);
38 validate_sop_common_module(dataset, result.findings);
39 }
40
42 validate_wsi_image_module(dataset, result.findings);
43 validate_multiframe_dimension_module(dataset, result.findings);
44 }
45
47 validate_optical_path_module(dataset, result.findings);
48 }
49
51 validate_image_pixel_module(dataset, result.findings);
52 }
53
54 // Specimen Module is User Optional — info-level checks
56 validate_specimen_module(dataset, result.findings);
57 }
58
59 // Determine overall validity
60 for (const auto& finding : result.findings) {
61 if (finding.severity == validation_severity::error) {
62 result.is_valid = false;
63 break;
64 }
66 finding.severity == validation_severity::warning) {
67 result.is_valid = false;
68 break;
69 }
70 }
71
72 return result;
73}
void validate_general_series_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_optical_path_module(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void validate_specimen_module(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void validate_multiframe_dimension_module(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void validate_wsi_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_general_study_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 strict_mode
Strict mode - treat warnings as errors.
bool validate_pixel_data
Validate pixel data consistency (rows, columns, bits)
bool check_type2
Check Type 2 (required, can be empty) attributes.
bool check_type1
Check Type 1 (required) attributes.
bool check_conditional
Check Type 1C/2C (conditionally required) attributes.
bool validate_optical_path
Validate optical path information.
bool validate_wsi_params
Validate WSI-specific image parameters.

References kcenon::pacs::services::validation::wsi_validation_options::check_conditional, kcenon::pacs::services::validation::wsi_validation_options::check_type1, kcenon::pacs::services::validation::wsi_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::wsi_validation_options::strict_mode, validate_general_series_module(), validate_general_study_module(), validate_image_pixel_module(), validate_multiframe_dimension_module(), kcenon::pacs::services::validation::wsi_validation_options::validate_optical_path, validate_optical_path_module(), validate_patient_module(), kcenon::pacs::services::validation::wsi_validation_options::validate_pixel_data, validate_sop_common_module(), validate_specimen_module(), validate_wsi_image_module(), kcenon::pacs::services::validation::wsi_validation_options::validate_wsi_params, and kcenon::pacs::services::validation::warning.

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

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

Definition at line 163 of file wsi_iod_validator.cpp.

165 {
166
167 // Type 1
168 if (options_.check_type1) {
169 check_type1_attribute(dataset, tags::modality, "Modality", findings);
171 "SeriesInstanceUID", findings);
172
173 // Modality must be "SM"
174 check_modality(dataset, findings);
175 }
176
177 // Type 2
178 if (options_.check_type2) {
179 check_type2_attribute(dataset, tags::series_number, "SeriesNumber",
180 findings);
181 }
182}
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
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::wsi_validation_options::check_type1, check_type1_attribute(), kcenon::pacs::services::validation::wsi_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::wsi_iod_validator::validate_general_study_module ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private

Definition at line 139 of file wsi_iod_validator.cpp.

141 {
142
143 // Type 1
144 if (options_.check_type1) {
146 "StudyInstanceUID", findings);
147 }
148
149 // Type 2
150 if (options_.check_type2) {
151 check_type2_attribute(dataset, tags::study_date, "StudyDate",
152 findings);
153 check_type2_attribute(dataset, tags::study_time, "StudyTime",
154 findings);
156 "ReferringPhysicianName", findings);
157 check_type2_attribute(dataset, tags::study_id, "StudyID", findings);
159 "AccessionNumber", findings);
160 }
161}
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::wsi_validation_options::check_type1, check_type1_attribute(), kcenon::pacs::services::validation::wsi_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::wsi_iod_validator::validate_image_pixel_module ( const core::dicom_dataset & dataset,
std::vector< validation_finding > & findings ) const
private

Definition at line 286 of file wsi_iod_validator.cpp.

288 {
289
290 // Type 1 attributes
291 if (options_.check_type1) {
293 "SamplesPerPixel", findings);
295 "PhotometricInterpretation", findings);
296 check_type1_attribute(dataset, tags::rows, "Rows", findings);
297 check_type1_attribute(dataset, tags::columns, "Columns", findings);
298 check_type1_attribute(dataset, tags::bits_allocated, "BitsAllocated",
299 findings);
300 check_type1_attribute(dataset, tags::bits_stored, "BitsStored",
301 findings);
302 check_type1_attribute(dataset, tags::high_bit, "HighBit", findings);
304 "PixelRepresentation", findings);
305 }
306
307 // Validate pixel data consistency
309 check_pixel_data_consistency(dataset, findings);
310 }
311}
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::wsi_validation_options::check_type1, check_type1_attribute(), kcenon::pacs::core::tags::columns, kcenon::pacs::core::tags::high_bit, options_, kcenon::pacs::core::tags::photometric_interpretation, kcenon::pacs::core::tags::pixel_representation, kcenon::pacs::core::tags::rows, kcenon::pacs::core::tags::samples_per_pixel, and kcenon::pacs::services::validation::wsi_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_multiframe_dimension_module()

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

Definition at line 263 of file wsi_iod_validator.cpp.

265 {
266
267 // Dimension Organization Type is Type 1
269 "DimensionOrganizationType", findings);
270
271 // Validate the Dimension Organization Type value
273 auto org_type =
275 if (org_type != "TILED_FULL" && org_type != "TILED_SPARSE") {
276 findings.push_back(
279 "DimensionOrganizationType must be 'TILED_FULL' or "
280 "'TILED_SPARSE' for WSI, found: " + org_type,
281 "WSI-ERR-001"});
282 }
283 }
284}
constexpr core::dicom_tag dimension_organization_type
Dimension Organization Type (0020,9311)

References check_type1_attribute(), kcenon::pacs::core::dicom_dataset::contains(), kcenon::pacs::services::validation::wsi_iod_tags::dimension_organization_type, kcenon::pacs::services::validation::error, and kcenon::pacs::core::dicom_dataset::get_string().

Referenced by validate().

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

◆ validate_optical_path_module()

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

Definition at line 240 of file wsi_iod_validator.cpp.

242 {
243
244 // Optical Path Module — Optical Path Identifier is Type 1
245 if (options_.check_type1) {
247 "OpticalPathIdentifier", findings);
248 }
249
250 // Optical Path Description is Type 3 (optional), info if missing
253 findings.push_back(
256 "OpticalPathDescription (0048,0106) not present - optical "
257 "path details unavailable",
258 "WSI-INFO-003"});
259 }
260 }
261}
constexpr core::dicom_tag optical_path_description
Optical Path Description (0048,0106)
constexpr core::dicom_tag optical_path_identifier
Optical Path Identifier (0048,0105)
@ info
Informational - suggestion for improvement.

References kcenon::pacs::services::validation::wsi_validation_options::check_conditional, kcenon::pacs::services::validation::wsi_validation_options::check_type1, check_type1_attribute(), kcenon::pacs::core::dicom_dataset::contains(), kcenon::pacs::services::validation::info, kcenon::pacs::services::validation::wsi_iod_tags::optical_path_description, kcenon::pacs::services::validation::wsi_iod_tags::optical_path_identifier, and options_.

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

Definition at line 122 of file wsi_iod_validator.cpp.

124 {
125
126 // Patient Module - All attributes are Type 2
127 if (options_.check_type2) {
128 check_type2_attribute(dataset, tags::patient_name, "PatientName",
129 findings);
130 check_type2_attribute(dataset, tags::patient_id, "PatientID",
131 findings);
133 "PatientBirthDate", findings);
134 check_type2_attribute(dataset, tags::patient_sex, "PatientSex",
135 findings);
136 }
137}
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::wsi_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_sop_common_module()

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

Definition at line 337 of file wsi_iod_validator.cpp.

339 {
340
341 // Type 1
342 if (options_.check_type1) {
343 check_type1_attribute(dataset, tags::sop_class_uid, "SOPClassUID",
344 findings);
346 "SOPInstanceUID", findings);
347 }
348
349 // Validate SOP Class UID is a WSI storage class
350 if (dataset.contains(tags::sop_class_uid)) {
351 auto sop_class = dataset.get_string(tags::sop_class_uid);
353 findings.push_back(
355 "SOPClassUID is not a recognized WSI Storage SOP Class: " +
356 sop_class,
357 "WSI-ERR-002"});
358 }
359 }
360}
bool is_wsi_storage_sop_class(std::string_view uid) noexcept
Check if a SOP Class UID is a WSI Storage SOP Class.

References kcenon::pacs::services::validation::wsi_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_wsi_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_specimen_module()

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

Definition at line 313 of file wsi_iod_validator.cpp.

315 {
316
317 // Specimen Module is User Optional (U) for WSI
318 // Provide info-level findings when specimen data is absent
319
321 findings.push_back(
323 "SpecimenIdentifier (0040,0551) not present - specimen "
324 "tracking unavailable",
325 "WSI-INFO-004"});
326 }
327
329 findings.push_back(
331 "ContainerIdentifier (0040,0512) not present - container "
332 "tracking unavailable",
333 "WSI-INFO-005"});
334 }
335}
constexpr core::dicom_tag container_identifier
Container Identifier (0040,0512)
constexpr core::dicom_tag specimen_identifier
Specimen Identifier (0040,0551)

References kcenon::pacs::services::validation::wsi_iod_tags::container_identifier, kcenon::pacs::core::dicom_dataset::contains(), kcenon::pacs::services::validation::info, and kcenon::pacs::services::validation::wsi_iod_tags::specimen_identifier.

Referenced by validate().

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

◆ validate_wsi_image_module()

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

Definition at line 184 of file wsi_iod_validator.cpp.

186 {
187
188 // WSI Image Module (PS3.3 Section C.8.12.4)
189
190 // ImageType is Type 1
191 if (options_.check_type1) {
192 check_type1_attribute(dataset, tags::image_type, "ImageType",
193 findings);
194 }
195
196 // Total Pixel Matrix Columns/Rows are Type 1
198 "TotalPixelMatrixColumns", findings);
200 "TotalPixelMatrixRows", findings);
201
202 // Number of Frames is Type 1 for multi-frame WSI
203 if (options_.check_type1) {
205 "NumberOfFrames", findings);
206 }
207
208 // Informational checks for WSI-specific attributes
210 // Imaged Volume Width/Height — important for physical measurements
212 findings.push_back(
214 "ImagedVolumeWidth (0048,0001) not present - physical "
215 "dimensions unavailable",
216 "WSI-INFO-001"});
217 }
218
220 findings.push_back(
222 "ImagedVolumeHeight (0048,0002) not present - physical "
223 "dimensions unavailable",
224 "WSI-INFO-002"});
225 }
226
227 // Image Orientation (Slide) is Type 1C
230 findings.push_back(
233 "ImageOrientationSlide (0048,0102) missing - slide "
234 "orientation unknown",
235 "WSI-WARN-001"});
236 }
237 }
238}
constexpr core::dicom_tag imaged_volume_width
Imaged Volume Width (0048,0001) — physical width in mm.
constexpr core::dicom_tag image_orientation_slide
Image Orientation (Slide) (0048,0102)
constexpr core::dicom_tag number_of_frames
Number of Frames (0028,0008)
constexpr core::dicom_tag imaged_volume_height
Imaged Volume Height (0048,0002) — physical height in mm.

References kcenon::pacs::services::validation::wsi_validation_options::check_conditional, kcenon::pacs::services::validation::wsi_validation_options::check_type1, check_type1_attribute(), kcenon::pacs::core::dicom_dataset::contains(), kcenon::pacs::services::validation::wsi_iod_tags::image_orientation_slide, kcenon::pacs::core::tags::image_type, kcenon::pacs::services::validation::wsi_iod_tags::imaged_volume_height, kcenon::pacs::services::validation::wsi_iod_tags::imaged_volume_width, kcenon::pacs::services::validation::info, kcenon::pacs::services::validation::wsi_iod_tags::number_of_frames, options_, kcenon::pacs::services::validation::wsi_iod_tags::total_pixel_matrix_columns, kcenon::pacs::services::validation::wsi_iod_tags::total_pixel_matrix_rows, 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:

Member Data Documentation

◆ options_


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