11. Radiology Report Drafting
Radiology reports document imaging findings in structured formats. Drafting reports from image analysis and dictation saves radiologist time on documentation while ensuring consistent formatting.
The standard report structure includes: clinical indication, technique, findings, and impression. The impression section synthesizes findings into diagnostic conclusions. Reports must be accurate, complete, and clearly communicate actionable findings.
# radiology_report_draft.py
from dataclasses import dataclass
from typing import Optional, List
import json
@dataclass
class RadiologyReport:
clinical_indication: str
technique: str
findings: List[str]
impression: str
class RadiologyReportDraft:
"""Draft radiology reports from findings data."""
REPORT_TEMPLATE = """Draft a complete radiology report from the provided information.
Follow standard radiology report format:
- CLINICAL INDICATION
- TECHNIQUE
- FINDINGS
- IMPRESSION
Use professional radiology terminology.
The Impression should summarize key findings and provide differential considerations if relevant.
Flag any critical/urgent findings in the Impression.
Information:
{information}
Study Type: {study_type}
Format the report with clear section headers."""
CRITIQUE_PROMPT = """Review this draft radiology report for:
1. Accuracy of findings interpretation
2. Completeness (all expected anatomy mentioned)
3. Appropriate use of clinical terminology
4. Impression appropriately summarizes findings
5. Any discrepancies between Findings and Impression
Report to review:
{report}
Return critique as JSON with issues identified."""
def __init__(self, ollama_client):
self.ollama = ollama_client
def draft_from_findings(self, findings: dict,
study_type: str) -> RadiologyReport:
"""Generate report from structured findings data."""
prompt = self.REPORT_TEMPLATE.format(
information=json.dumps(findings, indent=2),
study_type=study_type
)
response = self.ollama.generate(prompt)
return self._parse_report(response)
def draft_from_dictation(self, dictation: str,
study_type: str,
prior_reports: Optional[List[str]] = None) -> RadiologyReport:
"""Generate report from voice dictation."""
context = f"Dictation transcript:\n{dictation}"
if prior_reports:
context += f"\n\nPrior imaging for comparison:\n" + "\n".join(prior_reports)
prompt = self.REPORT_TEMPLATE.format(
information=context,
study_type=study_type
)
response = self.ollama.generate(prompt)
return self._parse_report(response)
def draft_comparison(self, current_findings: dict,
prior_report: str) -> RadiologyReport:
"""Generate report comparing to prior study."""
prompt = f"""Draft a comparison radiology report.
Current Study Findings:
{json.dumps(current_findings, indent=2)}
Prior Report for Comparison:
{prior_report}
Highlight:
- New findings compared to prior
- Resolved or improved findings
- Stable findings
- Any discrepancies with prior
Follow standard report format."""
response = self.ollama.generate(prompt)
return self._parse_report(response)
def critique_report(self, report: RadiologyReport) -> dict:
"""Review draft report for quality issues."""
prompt = self.CRITIQUE_PROMPT.format(
report=self._format_report_text(report)
)
response = self.ollama.generate(prompt)
try:
return json.loads(response)
except:
return {"issues": [], "overall_quality": "unknown"}
def _parse_report(self, response: str) -> RadiologyReport:
"""Parse LLM output into RadiologyReport structure."""
sections = {
"clinical_indication": "",
"technique": "",
"findings": [],
"impression": ""
}
current_section = None
for line in response.split("\n"):
line = line.strip()
if "CLINICAL INDICATION" in line.upper():
current_section = "clinical_indication"
continue
elif "TECHNIQUE" in line.upper():
current_section = "technique"
continue
elif "FINDINGS" in line.upper():
current_section = "findings"
continue
elif "IMPRESSION" in line.upper():
current_section = "impression"
continue
if current_section and line:
if current_section == "findings":
if line.startswith("-") or line.startswith("•"):
sections["findings"].append(line.lstrip("-• "))
elif not line.startswith("FINDINGS"):
sections["findings"].append(line)
else:
sections[current_section] += line + " "
return RadiologyReport(
clinical_indication=sections["clinical_indication"].strip(),
technique=sections["technique"].strip(),
findings=sections["findings"],
impression=sections["impression"].strip()
)
def _format_report_text(self, report: RadiologyReport) -> str:
return f"""CLINICAL INDICATION: {report.clinical_indication}
TECHNIQUE: {report.technique}
FINDINGS: {'; '.join(report.findings)}
IMPRESSION: {report.impression}"""
Radiology reports carry medicolegal weight. Incorrect reports cause patient harm and provider liability. Draft reports require radiologist review and verification before clinical use. The value lies in reducing documentation burden, not in autonomous reporting.
Take three dictations of varying quality (one clear, one fragmented, one with background noise). Generate reports from each and evaluate format consistency and clinical coherence.