Skip to main content

Project policies

A policy adds your project's metadata requirements to the built-in checks. Use it for approved descriptions, empty comment fields, de-identification declarations, or a specific patient-ID format. dicomqc checks the files; it does not change them.

Try the policy demo​

The demo creates one synthetic DICOM file in candidate/ and a separate, corrected file in corrected/. Both use sub-001 for PatientName and PatientID, with no birth date or private tags. These fields differ:

DICOM fieldCandidate valueDemo policy requirementCorrected value
PatientIdentityRemovedNOExactly YES, at the top levelYES
StudyDescriptionT1w - Example PatientExactly T1w or T2wT1w
PatientCommentsSynthetic identifying commentAbsent or emptyAbsent

These are invented values shown to explain the example. The generated reports do not display them.

Generate the files, their three-rule policy.yaml, and both audits:

dicomqc demo --policy-demo --output-dir dicomqc-policy-demo

The candidate passes the built-in checks alone. With the project policy, each row above produces one error: the identity-removal declaration is not YES, the description is outside the approved list, and the comment is populated. Open dicomqc-policy-demo/before.html to see all three findings in one file.

Before: three project-policy errors

HTML policy report showing three project-policy issues without exposing observed metadata values.

The corrected file satisfies all three requirements and the built-in checks: zero errors, zero warnings, and no findings. Open dicomqc-policy-demo/after.html to see the passing audit. dicomqc creates these separate synthetic examples; its audits never edit the files.

After: all checked metadata passes

HTML policy report for the corrected synthetic file, showing checks passed and no findings.

To rerun the two audits explicitly:

dicomqc scan dicomqc-policy-demo/candidate/ \
--policy dicomqc-policy-demo/policy.yaml --html candidate-audit.html

dicomqc scan dicomqc-policy-demo/corrected/ \
--policy dicomqc-policy-demo/policy.yaml --html corrected-audit.html

The first scan returns exit code 2; the second returns 0. The demo command itself returns 0 when both examples produce the expected results. It also writes before.json, before.csv, after.json, and after.csv alongside the HTML. See the output formats reference for JSON and CSV contents, and HTML review controls for filters and printing.

Use your own policy​

In the desktop app's privacy mode, expand Advanced setup, then use Project policy > New policy or Choose YAML. The Policy workspace provides YAML highlighting, line numbers, search, undo, and validation with the dicomqc engine. Save as and use writes a new file and selects it without overwriting the original. Save the policy outside DICOM input folders. Saving the .dicomqc project embeds a copy of the selected YAML. Completed desktop audits also retain their policy alongside the reports. Remove policy returns to the built-in checks without deleting the YAML file.

The separate four-rule example below uses different approved descriptions and adds a patient-ID format check. It is not the demo's generated policy. Save it as research.yaml, outside your DICOM input directory:

version: 1
id: research-example
rules:
- id: no-patient-comments
keyword: PatientComments
check: absent_or_empty

- id: approved-study-description
keyword: StudyDescription
check: allowed_values
values: ["Brain MRI", "Chest CT"]

- id: identity-removal-declared
keyword: PatientIdentityRemoved
scope: top_level
check: allowed_values
values: ["YES"]

- id: patient-id-format
keyword: PatientID
scope: top_level
check: matches
pattern: "sub-[0-9][0-9][0-9]"

Change the allowed descriptions and ID format to match your project, then run:

dicomqc scan candidate/ --policy research.yaml --html policy-report.html

The same example is in examples/policies/research.yaml in the repository. To apply a policy during a dataset comparison:

dicomqc compare source/ candidate/ --manifest pairs.csv \
--policy research.yaml --html comparison.html

Comparison policies apply only to readable, listed candidate files, not to the original source files. Keep the policy, manifest, and reports outside both DICOM directories. Report outputs must not overwrite the policy file.

Choose checks​

checkRequirementExtra field
absent_or_emptyThe field is missing or empty.None
nonemptyThe field exists and contains a value.None
allowed_valuesEvery value exactly matches an approved string.values: list of quoted strings
matchesEvery value matches a full-string, case-sensitive shell pattern.pattern: quoted string

nonempty, allowed_values, and matches fail when the field is missing or empty. Whitespace-only values count as empty; other values are not trimmed before matching. Each component of a multi-valued field must pass. Matching is case-sensitive. Patterns use * for any number of characters, ? for one character, and [0-9] for one digit; they are not regular expressions. For example, sub-[0-9][0-9][0-9] accepts sub-001, but not sub-1 or sub-001-extra.

Each rule needs a unique id, a standard DICOM keyword, and a check. Optional severity is error (default), warning, or info. Use non-identifying policy and rule IDs: they appear in reports. Quote allowed values, including "YES", "NO", numbers, and dates, so YAML treats them as strings.

The default scope: all checks every occurrence, including fields inside sequences. A passing occurrence does not hide a failing one. Use scope: top_level when a field must be present on the main DICOM dataset; a nested field cannot satisfy that requirement. scope: all does not require the field to exist in every sequence item.

Invalid policies stop the command. Unknown fields and keywords, duplicate rule IDs, and inappropriate options are rejected rather than ignored.

Policy format limits
  • Policy and rule IDs are lowercase slugs, such as brain-mri-v1, up to 64 characters.
  • A UTF-8 YAML file can contain up to 100 rules and be at most 64 KiB.
  • An allowed-value list can contain up to 100 strings. Strings and patterns are limited to 256 characters.
  • YAML aliases, anchors, and explicit type tags are not supported.
  • Binary fields, including pixel data, cannot be selected. Sequence fields support only absent_or_empty and nonempty; the latter checks for at least one item, not the contents of that item. To check an inner field, name its keyword in a separate rule with scope: all.

What these checks mean​

Operator-entered descriptions can contain names or other identifying details. An approved-value list can catch unexpected text without discarding useful acquisition descriptions. A populated description is not automatically unsafe; the list is a project decision. DICOM Clean Descriptors Option.

Project-specific IDs and de-identification declarations are used in real workflows: the RICORD protocol specifies site-prefixed patient IDs and sets PatientIdentityRemoved to YES. The example above is not an implementation of that protocol. RSNA RICORD de-identification protocol.

A declaration is not proof

PatientIdentityRemoved: YES only records what the producer declared. A policy cannot prove that de-identification succeeded. dicomqc does not inspect pixels, perform OCR, or certify a DICOM confidentiality profile.

Policies are additive: they do not disable or replace the built-in checks. A project ID pattern may pass while the built-in pseudonym-format check still warns. Review both findings; passing a project policy is not a sharing decision.

By default, policy reports omit observed tag values and the policy's allowed strings and patterns. Policy-scan JSON also omits raw study/series UIDs, manufacturer, and modality from its record context; ordinary scan JSON still includes those fields.

Adding --vendor-summary explicitly includes declared scanner/software labels and private creator labels in HTML, JSON, and MultiQC, even with a policy. Those labels may contain identifying information; a passing policy does not establish that they are safe to share. Private payload values and policy configuration contents remain excluded. See Scanner inventory.

JSON records the policy's id and SHA-256 file digest in a policy object; HTML and MultiQC show them in the supporting audit details. Keep the policy file with the audit records so reviewers can reproduce the check. File paths and policy/rule IDs remain visible. Use non-identifying IDs and review paths before sharing a report.