21 "1.2.840.10008.5.1.4.1.1.66.8";
29 : options_(options) {}
71 for (
const auto& finding : result.
findings) {
93 for (
const auto& finding : result.
findings) {
114 if (modality !=
"SEG")
return false;
120 if (seg_type !=
"LABELMAP")
return false;
151 std::vector<validation_finding>& findings)
const {
167 std::vector<validation_finding>& findings)
const {
181 "ReferringPhysicianName", findings);
191 std::vector<validation_finding>& findings)
const {
203 "FrameOfReferenceUID", findings);
215 [[maybe_unused]] std::vector<validation_finding>& findings)
const {
222 std::vector<validation_finding>& findings)
const {
227 "Manufacturer", findings);
233 std::vector<validation_finding>& findings)
const {
238 "Manufacturer", findings);
241 "ManufacturerModelName", findings);
244 "DeviceSerialNumber", findings);
247 "SoftwareVersions", findings);
253 std::vector<validation_finding>& findings)
const {
256 constexpr dicom_tag instance_number{0x0020, 0x0013};
258 dataset, instance_number,
"InstanceNumber", findings);
264 std::vector<validation_finding>& findings)
const {
271 "PhotometricInterpretation", findings);
284 "PixelRepresentation", findings);
294 std::vector<validation_finding>& findings)
const {
299 "SegmentationType", findings);
302 "SegmentSequence", findings);
311 std::vector<validation_finding>& findings)
const {
318 if (!element || !element->is_sequence()
319 || element->sequence_items().empty()) {
323 "SegmentSequence must contain at least one segment",
329 const auto& sequence = element->sequence_items();
330 for (
size_t i = 0; i < sequence.size(); ++i) {
331 const auto& segment_item = sequence[i];
337 for (
size_t i = 0; i < sequence.size(); ++i) {
339 auto seg_num = sequence[i].get_numeric<uint16_t>(
341 if (seg_num && *seg_num !=
static_cast<uint16_t
>(i + 1)) {
345 "Segment[" + std::to_string(i) +
"]: "
346 "SegmentNumber should be " + std::to_string(i + 1)
347 +
" for Label Map (contiguous from 1), found: "
348 + std::to_string(*seg_num),
358 size_t segment_index,
359 std::vector<validation_finding>& findings)
const {
361 std::string prefix =
"Segment[" + std::to_string(segment_index) +
"]: ";
367 prefix +
"SegmentNumber (0062,0004) is required",
376 prefix +
"SegmentLabel (0062,0005) is required",
385 prefix +
"SegmentAlgorithmType (0062,0008) is required",
392 if (algo_type !=
"AUTOMATIC" && algo_type !=
"SEMIAUTOMATIC"
393 && algo_type !=
"MANUAL") {
397 prefix +
"Invalid SegmentAlgorithmType value: " + algo_type,
408 prefix +
"SegmentedPropertyCategoryCodeSequence (0062,0003) "
419 prefix +
"SegmentedPropertyTypeCodeSequence (0062,000F) "
432 prefix +
"SegmentLabel should not be empty",
442 std::vector<validation_finding>& findings)
const {
447 "NumberOfFrames", findings);
450 "SharedFunctionalGroupsSequence", findings);
454 "PerFrameFunctionalGroupsSequence", findings);
460 std::vector<validation_finding>& findings)
const {
465 "DimensionOrganizationSequence", findings);
468 "DimensionIndexSequence", findings);
474 std::vector<validation_finding>& findings)
const {
482 "ReferencedSeriesSequence (0008,1115) should be present "
483 "for source image references",
492 std::vector<validation_finding>& findings)
const {
507 "SOPClassUID is not Label Map Segmentation Storage: "
522 std::string_view
name,
523 std::vector<validation_finding>& findings)
const {
529 std::string(
"Type 1 attribute missing: ") + std::string(
name)
531 "LMSEG-TYPE1-MISSING"
534 const auto* element = dataset.
get(tag);
535 if (element !=
nullptr) {
536 if (element->is_sequence()) {
537 if (element->sequence_items().empty()) {
541 std::string(
"Type 1 sequence has no items: ")
553 std::string(
"Type 1 attribute has empty value: ")
567 std::string_view
name,
568 std::vector<validation_finding>& findings)
const {
574 std::string(
"Type 2 attribute missing: ") + std::string(
name)
576 "LMSEG-TYPE2-MISSING"
583 std::vector<validation_finding>& findings)
const {
590 if (modality !=
"SEG") {
594 "Modality must be 'SEG' for Label Map Segmentation objects, "
595 "found: " + modality,
603 std::vector<validation_finding>& findings)
const {
611 if (seg_type !=
"LABELMAP") {
615 "SegmentationType must be 'LABELMAP' for Label Map Segmentation "
616 "objects, found: " + seg_type,
624 std::vector<validation_finding>& findings)
const {
628 if (samples && *samples != 1) {
632 "SamplesPerPixel must be 1 for Label Map Segmentation objects",
641 if (photometric !=
"MONOCHROME2") {
645 "PhotometricInterpretation must be MONOCHROME2 for "
646 "Label Map Segmentation",
654 if (bits_allocated) {
655 if (*bits_allocated != 8 && *bits_allocated != 16) {
659 "BitsAllocated should be 8 or 16 for Label Map "
660 "Segmentation (unsigned integer labels), found: "
661 + std::to_string(*bits_allocated),
670 if (pixel_rep && *pixel_rep != 0) {
674 "PixelRepresentation must be 0 (unsigned) for Label Map "
675 "Segmentation -- label values must be unsigned integers",
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.
label_map_seg_validation_options options_
void validate_label_map_segmentation_image_module(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_general_equipment_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
label_map_seg_iod_validator()=default
Construct validator with default options.
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
bool quick_check(const core::dicom_dataset &dataset) const
Quick check if dataset has minimum required attributes.
void validate_label_map_segmentation_series_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
validation_result validate(const core::dicom_dataset &dataset) const
Validate a DICOM dataset against Label Map Segmentation IOD.
void validate_sop_common_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_general_image_module(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void validate_multiframe_functional_groups_module(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
const label_map_seg_validation_options & options() const noexcept
Get the validation options.
void check_segmentation_type(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void validate_single_segment(const core::dicom_dataset &segment_item, size_t segment_index, std::vector< validation_finding > &findings) const
void validate_common_instance_reference_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
void validate_segment_sequence(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 set_options(const label_map_seg_validation_options &options)
Set validation options.
void validate_general_series_module(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void validate_enhanced_general_equipment_module(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
void check_modality(const core::dicom_dataset &dataset, std::vector< validation_finding > &findings) const
Compile-time constants for commonly used DICOM tags.
Label Map Segmentation IOD Validator.
@ contains
CONTAINS - Parent contains child.
constexpr std::string_view label_map_segmentation_storage_uid
Label Map Segmentation Storage SOP Class UID (Supplement 243)
segmentation_type
Segmentation type (0062,0001)
bool is_valid_label_map_seg_dataset(const core::dicom_dataset &dataset)
Quick check if a dataset is a valid Label Map Segmentation object.
validation_result validate_label_map_seg_iod(const core::dicom_dataset &dataset)
Validate a Label Map Segmentation dataset with default options.
@ warning
Non-critical - IOD may have issues.
@ error
Critical - IOD is non-compliant.
bool is_label_map_segmentation(const core::dicom_dataset &dataset)
Check if dataset is a label map segmentation.
Options for Label Map Segmentation IOD validation.
bool check_type1
Check Type 1 (required) attributes.
bool check_type2
Check Type 2 (required, can be empty) attributes.
bool validate_label_map_instance
Validate label map-specific instance attributes.
bool validate_pixel_data
Validate pixel data consistency for label map.
bool strict_mode
Strict mode - treat warnings as errors.
bool validate_segment_sequence
Validate Segment Sequence structure.
bool validate_references
Validate referenced series/instances.
bool validate_algorithm_info
Validate segment algorithm identification.
bool check_conditional
Check Type 1C/2C (conditionally required) attributes.
Result of IOD validation.
std::vector< validation_finding > findings
All findings during validation.
bool is_valid
Overall validation status.