Skip to content

Add structured standards export: FHIR DiagnosticReport + DICOM SR #54

Description

@Liohtml

Part of #51.

Summary

Add additional report output formats alongside the existing PDF/HTML/JSON:
a FHIR DiagnosticReport (JSON) and an optional DICOM Structured Report
(SR, TID 1500)
. These make MedCheck's output consumable by EHRs, PACS, and
research data platforms — without touching the human-readable reports we already
generate.

Why (vision)

Right now the structured output is a bespoke JSON schema. Emitting
standards-compliant artifacts means another system (a hospital EHR, an imaging
data platform, a downstream validator) can ingest MedCheck results directly, and
it positions findings within recognized terminologies. This is the
"machine-readable, interoperable" companion to the human PDF — purely additive.

Recommended components (license-verified)

  • FHIR specCC0 (public domain). Python: fhir.resources (BSD,
    Pydantic v2, R4/R5) — clean fit. Emit DiagnosticReport (+ optionally
    ImagingStudy, Observation per finding).
  • DICOM SR — produced via highdicom.sr (MIT, built on pydicom),
    implementing TID 1500 "Measurement Report". Optional, only when DICOM
    evidence images are available.
  • Coding — reference RadLex RID and RadElement CDE identifiers in the
    coded content. ⚠️ RadLex / RadReport carry custom RSNA licenses: attribution
    required, identifiers must not be altered, the ontology must not be
    embedded/modified
    — we only reference IDs, never bundle the ontology.

Where

  • New optional extra: interop = ["fhir.resources>=7", "highdicom>=0.22"].
  • src/medcheck/pipeline/report.py:
    • generate_fhir_report(ctx) -> str (JSON DiagnosticReport)
    • generate_dicom_sr(ctx) -> str (writes a .dcm SR; requires source DICOM)
    • extend ReportStep.run() to handle report_format in {"fhir", "sr"} and/or
      allow emitting them in addition to the primary format.
  • CLI: extend --report choices (pdf|html|json|fhir|sr) and/or add
    --also-emit fhir,sr.
  • Map StructureFinding → FHIR Observation / SR content items; carry
    confidence, status, anatomy, and the existing disclaimer/limitations.

Design constraints

  • Lazy import of fhir.resources / highdicom; skip with a clear message if
    the interop extra isn't installed.
  • DICOM SR requires the original DICOM datasets (study/series/SOP references) —
    only enabled when ingest provided real DICOM; otherwise skip SR and still emit FHIR.
  • Keep PDF/HTML/JSON exactly as-is (additive).

Acceptance criteria

  • fhir output produces a schema-valid DiagnosticReport JSON (validated by
    fhir.resources model construction).
  • sr output writes a TID 1500 SR when source DICOM is available; skips
    gracefully otherwise.
  • RadLex/RadElement IDs referenced (not embedded), with attribution noted in docs.
  • Lazy imports; no new hard dependencies.
  • Tests: FHIR document builds & round-trips; SR built from a mocked/sample
    dataset; formats are additive (PDF/HTML/JSON unaffected).
  • Docs: new formats, the interop extra, and the RSNA attribution note.

Effort

~1 day (FHIR first; DICOM SR as a follow-on). Light optional deps.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions