21 "1.2.840.10008.5.1.4.1.1.66.7";
29 : options_(options) {}
69 for (
const auto& finding : result.
findings) {
91 for (
const auto& finding : result.
findings) {
114 if (modality !=
"SEG")
return false;
119 if (seg_type !=
"HEIGHTMAP")
return false;
150 std::vector<validation_finding>& findings)
const {
166 std::vector<validation_finding>& findings)
const {
180 "ReferringPhysicianName", findings);
190 std::vector<validation_finding>& findings)
const {
202 "FrameOfReferenceUID", findings);
213 [[maybe_unused]] std::vector<validation_finding>& findings)
const {
221 std::vector<validation_finding>& findings)
const {
231 std::vector<validation_finding>& findings)
const {
236 "Manufacturer", findings);
239 "ManufacturerModelName", findings);
242 "DeviceSerialNumber", findings);
245 "SoftwareVersions", findings);
251 std::vector<validation_finding>& findings)
const {
254 constexpr dicom_tag instance_number{0x0020, 0x0013};
256 dataset, instance_number,
"InstanceNumber", findings);
262 std::vector<validation_finding>& findings)
const {
269 "PhotometricInterpretation", findings);
282 "PixelRepresentation", findings);
291 std::vector<validation_finding>& findings)
const {
296 "SegmentationType", findings);
299 "SegmentSequence", findings);
308 std::vector<validation_finding>& findings)
const {
316 if (!element || !element->is_sequence()
317 || element->sequence_items().empty()) {
321 "SegmentSequence must contain at least one segment",
327 const auto& sequence = element->sequence_items();
328 for (
size_t i = 0; i < sequence.size(); ++i) {
329 const auto& segment_item = sequence[i];
336 size_t segment_index,
337 std::vector<validation_finding>& findings)
const {
339 std::string prefix =
"Segment[" + std::to_string(segment_index) +
"]: ";
346 prefix +
"SegmentNumber (0062,0004) is required",
355 prefix +
"SegmentLabel (0062,0005) is required",
364 prefix +
"SegmentAlgorithmType (0062,0008) is required",
370 if (algo_type !=
"AUTOMATIC" && algo_type !=
"SEMIAUTOMATIC"
371 && algo_type !=
"MANUAL") {
375 prefix +
"Invalid SegmentAlgorithmType value: " + algo_type,
387 prefix +
"SegmentedPropertyCategoryCodeSequence (0062,0003) "
399 prefix +
"SegmentedPropertyTypeCodeSequence (0062,000F) "
413 prefix +
"SegmentLabel should not be empty",
422 std::vector<validation_finding>& findings)
const {
427 "NumberOfFrames", findings);
430 "SharedFunctionalGroupsSequence", findings);
433 "PerFrameFunctionalGroupsSequence", findings);
439 std::vector<validation_finding>& findings)
const {
444 "DimensionOrganizationSequence", findings);
447 "DimensionIndexSequence", findings);
453 std::vector<validation_finding>& findings)
const {
460 "ReferencedSeriesSequence (0008,1115) should be present "
461 "for source image references",
470 std::vector<validation_finding>& findings)
const {
486 "SOPClassUID is not Heightmap Segmentation Storage: "
501 std::string_view
name,
502 std::vector<validation_finding>& findings)
const {
508 std::string(
"Type 1 attribute missing: ") + std::string(
name)
510 "HMSEG-TYPE1-MISSING"
513 const auto* element = dataset.
get(tag);
514 if (element !=
nullptr) {
515 if (element->is_sequence()) {
516 if (element->sequence_items().empty()) {
520 std::string(
"Type 1 sequence has no items: ")
531 std::string(
"Type 1 attribute has empty value: ")
544 std::string_view
name,
545 std::vector<validation_finding>& findings)
const {
551 std::string(
"Type 2 attribute missing: ") + std::string(
name)
553 "HMSEG-TYPE2-MISSING"
560 std::vector<validation_finding>& findings)
const {
567 if (modality !=
"SEG") {
571 "Modality must be 'SEG' for Heightmap Segmentation objects, "
572 "found: " + modality,
580 std::vector<validation_finding>& findings)
const {
588 if (seg_type !=
"HEIGHTMAP") {
592 "SegmentationType must be 'HEIGHTMAP' for Heightmap Segmentation "
593 "objects, found: " + seg_type,
601 std::vector<validation_finding>& findings)
const {
605 if (samples && *samples != 1) {
609 "SamplesPerPixel must be 1 for Heightmap Segmentation objects",
618 if (photometric !=
"MONOCHROME2") {
622 "PhotometricInterpretation must be MONOCHROME2 for "
623 "Heightmap Segmentation",
632 if (bits_allocated) {
633 if (*bits_allocated != 16 && *bits_allocated != 32) {
637 "BitsAllocated is typically 16 or 32 for Heightmap "
638 "Segmentation, found: "
639 + std::to_string(*bits_allocated),
auto get(dicom_tag tag) noexcept -> dicom_element *
Get a pointer to the element with the given tag.
auto get_numeric(dicom_tag tag) const -> std::optional< T >
Get the numeric value of an element.
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.
auto to_string() const -> std::string
Convert to string representation.
validation_result validate(const core::dicom_dataset &dataset) const
Validate a DICOM dataset against Heightmap Segmentation IOD.
void check_segmentation_type(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void validate_segment_sequence(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void validate_enhanced_general_equipment_module(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void check_pixel_data_consistency(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
validation_result validate_segments(const core::dicom_dataset &dataset) const
Validate segment sequence completeness.
void validate_multiframe_functional_groups_module(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void validate_multiframe_dimension_module(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void validate_sop_common_module(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
const heightmap_seg_validation_options & options() const noexcept
Get the validation options.
void validate_heightmap_segmentation_image_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
heightmap_seg_iod_validator()=default
Construct validator with default options.
void validate_single_segment(const core::dicom_dataset &segment_item, size_t segment_index, std::vector< validation_finding > &findings) const
void validate_heightmap_segmentation_series_module(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void set_options(const heightmap_seg_validation_options &options)
Set validation options.
void validate_common_instance_reference_module(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
bool quick_check(const core::dicom_dataset &dataset) const
Quick check if dataset has minimum required attributes.
void validate_general_image_module(const core::dicom_dataset &dataset, 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 validate_general_series_module(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void validate_general_study_module(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
heightmap_seg_validation_options options_
void validate_image_pixel_module(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void validate_patient_module(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void check_type1_attribute(const core::dicom_dataset &dataset, core::dicom_tag tag, std::string_view name, std::vector< validation_finding > &findings) const
Compile-time constants for commonly used DICOM tags.
Heightmap Segmentation IOD Validator.
constexpr std::string_view heightmap_segmentation_storage_uid
Heightmap Segmentation Storage SOP Class UID (Supplement 240)
segmentation_type
Segmentation type (0062,0001)
@ warning
Non-critical - IOD may have issues.
@ error
Critical - IOD is non-compliant.
validation_result validate_heightmap_seg_iod(const core::dicom_dataset &dataset)
Validate a Heightmap Segmentation dataset with default options.
bool is_heightmap_segmentation(const core::dicom_dataset &dataset)
Check if dataset is a heightmap segmentation.
bool is_valid_heightmap_seg_dataset(const core::dicom_dataset &dataset)
Quick check if a dataset is a valid Heightmap Segmentation object.
Options for Heightmap Segmentation IOD validation.
bool validate_pixel_data
Validate pixel data consistency for heightmap.
bool validate_segment_sequence
Validate Segment Sequence structure.
bool validate_references
Validate referenced series/instances.
bool check_conditional
Check Type 1C/2C (conditionally required) attributes.
bool check_type1
Check Type 1 (required) attributes.
bool validate_heightmap_instance
Validate heightmap-specific instance attributes.
bool validate_algorithm_info
Validate segment algorithm identification.
bool check_type2
Check Type 2 (required, can be empty) attributes.
bool strict_mode
Strict mode - treat warnings as errors.
Result of IOD validation.
std::vector< validation_finding > findings
All findings during validation.
bool is_valid
Overall validation status.