pacs_study_summary
Query PACS studies and generate complete interoperability mappings between DICOM, HL7, and FHIR standards for healthcare data integration.
Instructions
[Premium] Query a study from PACS and show its complete interoperability mapping. Returns: (1) study metadata from PACS, (2) DICOM-to-HL7 field mapping for key fields, (3) HL7-to-FHIR resource mapping, (4) a generated HL7 ORM^O01 message skeleton pre-filled with the study's actual data. This is the bridge between 'what's in PACS' and 'how do I represent it in HL7/FHIR'. Search by Study Instance UID or accession number.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| study_instance_uid | No | Study Instance UID to look up. | |
| accession_number | No | Accession number to look up (alternative to UID). |
Implementation Reference
- The handler function _handle_study_summary executes the tool logic, including fetching study data from PACS and generating the summary components.
def _handle_study_summary(arguments: dict) -> str: """Query a study from PACS and generate a complete interoperability summary.""" study_uid = arguments.get("study_instance_uid", "") accession = arguments.get("accession_number", "") if not study_uid and not accession: return "Provide either study_instance_uid or accession_number to look up a study." # Step 1: Query PACS for the study filters = QueryFilters(limit=1) if study_uid: filters.study_instance_uid = study_uid elif accession: filters.accession_number = accession results = pacs_find(filters) if not results: search_term = study_uid or accession return format_pacs_result(f"No study found matching: {search_term}") study = results[0] if not isinstance(study, StudyResult): return format_pacs_result("Unexpected result type from PACS query.") # Step 2: Build the interoperability summary lines = [ "PACS Study Interoperability Summary", "=" * 70, "", "SECTION 1: STUDY METADATA (from PACS)", "-" * 40, ] # Display study metadata study_data = study.model_dump() for key, value in study_data.items(): if value: label = key.replace("_", " ").title() lines.append(f" {label}: {value}") # Step 3: DICOM → HL7 mapping lines.extend([ "", "SECTION 2: DICOM → HL7 v2 FIELD MAPPING", "-" * 40, f" {'DICOM Tag':<25} {'Value':<25} {'HL7 Field':<15}", f" {'─' * 25} {'─' * 25} {'─' * 15}", ]) for field_name, dicom_tag, hl7_field in _KEY_STUDY_FIELDS: value = study_data.get(_camel_to_snake(field_name), "") if value: lines.append(f" {field_name:<25} {str(value)[:25]:<25} {hl7_field:<15}") # Step 4: HL7 → FHIR mapping lines.extend([ "", "SECTION 3: HL7 v2 → FHIR R4 RESOURCE MAPPING", "-" * 40, f" {'HL7 Field':<15} {'FHIR Resource':<25} {'FHIR Path':<30}", f" {'─' * 15} {'─' * 25} {'─' * 30}", ]) # Map the key HL7 fields to FHIR _hl7_to_fhir_quick = { "PID-3": ("Patient", "Patient.identifier"), "PID-5": ("Patient", "Patient.name"), "PID-7": ("Patient", "Patient.birthDate"), "PID-8": ("Patient", "Patient.gender"), "PV1-8": ("Encounter", "Encounter.participant"), "OBR-4": ("ServiceRequest", "ServiceRequest.code"), "OBR-7": ("ServiceRequest", "ServiceRequest.occurrenceDateTime"), "OBR-18": ("ServiceRequest", "ServiceRequest.identifier"), "OBR-24": ("ImagingStudy", "ImagingStudy.modality"), "MSH-4": ("MessageHeader", "MessageHeader.source.endpoint"), } for _, _, hl7_field in _KEY_STUDY_FIELDS: if hl7_field in _hl7_to_fhir_quick: fhir_resource, fhir_path = _hl7_to_fhir_quick[hl7_field] lines.append(f" {hl7_field:<15} {fhir_resource:<25} {fhir_path:<30}") # Step 5: Generate HL7 ORM^O01 skeleton lines.extend([ "", "SECTION 4: GENERATED HL7 ORM^O01 MESSAGE", "-" * 40, " (Pre-filled with study data from PACS)", "", ]) orm_message = _generate_orm(study) for seg in orm_message: lines.append(f" {seg}") # Step 6: Integration pattern reference lines.extend([ "", "SECTION 5: INTEGRATION CONTEXT", "-" * 40, " Pattern: Radiology Order-to-Result Workflow (IHE SWF)", " This study would typically flow through:", " 1. HIS/EHR sends ORM^O01 → Integration Engine", " 2. Integration Engine → RIS (order creation)", " 3. RIS → Modality Worklist (MWL C-FIND)", " 4. Modality acquires images → PACS (C-STORE)", " 5. RIS sends ORU^R01 (report) → Integration Engine → EHR", "", " Use 'explain_integration_pattern' with 'radiology workflow' for full details.", ]) return format_pacs_result("\n".join(lines)) - The inputSchema definition for pacs_study_summary.
inputSchema={ "type": "object", "properties": { "study_instance_uid": { "type": "string", "description": "Study Instance UID to look up.", "default": "", }, "accession_number": { "type": "string", "description": "Accession number to look up (alternative to UID).", "default": "", }, }, }, ), - src/dicom_hl7_mcp/tools/pacs_combined.py:23-50 (registration)The registration of pacs_study_summary within the PACS_COMBINED_TOOLS list.
PACS_COMBINED_TOOLS = [ Tool( name="pacs_study_summary", description=( "[Premium] Query a study from PACS and show its complete interoperability mapping. " "Returns: (1) study metadata from PACS, (2) DICOM-to-HL7 field mapping for key fields, " "(3) HL7-to-FHIR resource mapping, (4) a generated HL7 ORM^O01 message skeleton " "pre-filled with the study's actual data. This is the bridge between 'what's in PACS' " "and 'how do I represent it in HL7/FHIR'. " "Search by Study Instance UID or accession number." ), inputSchema={ "type": "object", "properties": { "study_instance_uid": { "type": "string", "description": "Study Instance UID to look up.", "default": "", }, "accession_number": { "type": "string", "description": "Accession number to look up (alternative to UID).", "default": "", }, }, }, ), ]