HCLS/ClinicalObservationsInteroperability/FHIR

From W3C Wiki

FHIR as RDF

HL7 has garnered a lot of attention around a project called FHIR (Fast Healthcare Interoperability Resources). For instance, the US Integrated Program Office has selected FHIR as an exchange format between US DOD's AHLTA and the US Vererances Administration's VISTA EHR sysem¹. This task is to provide useful RDF representations of FHIR resources, with the goal that the Semantic Web advantages of simple, uniform representation and connectivity within a greater network are manifest in that RDF representation.

¹ HIT Standards Committee NwHIN Power Team Transport Standards for Consumer / Exchanges: Preliminary June 19, 2013

RDF representation of FHIR resoruces

Mapping

Given an XML representation of a FHIR resource, e.g.:

<DiagnosticReport xmlns="http://hl7.org/fhir">
  <subject>
    <type value="Patient"/>
    <reference value="patient/@pat2"/>
  </subject>
  <diagnosticTime value="2011-03-04T08:30:00+11:00"/>
  <results>
    <name>
      <coding>
	<system value="http://loinc.org"/>
        <code value="15430-2"/>
	<display value="FULL BLOOD EXAMINATION"/>
      </coding>
    </name>
    <result>
      <type value="Observation"/>
      <reference value="#r1"/>
    </result>  
  </results>
</DiagnosticReport>

with some embedded or linked clinical observations:

  <contained>
    <Observation id="r1">
      <name>
	<coding>
	  <system value="http://loinc.org"/>
	  <code value="718-7"/>
	  <display value="Haemoglobin"/>
	</coding>
      </name>
      <valueQuantity>
	<value value="176"/>
	<units value="g/L"/>
	<system value="http://unitsofmeasure.org"/>
	<code value="g/L"/>
      </valueQuantity>
    </Observation>
  </contained> 

we represent the information in RDF as:

[] a fhir:DiagnosticReport;
  :subject [
    a fhir:Reference;
    Reference:reference <patient/@pat2>
  ];
  :results [
    :results_name [
      a fhir:Codeable;
        Codeable:coding [
          a fhir:Coding;
          Coding:system [a fhir:Uri; fhir:value <http://loinc.org>];
          Coding:code  [a fhir:Code; fhir:value "15430-2"];
          Coding:display  [a fhir:String; fhir:value "FULL BLOOD EXAMINATION"];
        ];
      ];
    :results_result [
      a fhir:Reference;
      Reference:reference _:r1
    ]
  ].

with corresponding clinical observations:

_:r1 a fhir:Observation;
  Observation:name [
    a fhir:Coding;
    Coding:system [a fhir:Uri; fhir:value <http://loinc.org/>];
    Coding:code [a fhir:Code; fhir:value "718-7"];
    Coding:display [a fhir:String; fhir:value "Haemoglobin"]
  ];
  Observation:valueQuantity [
     a fhir:Quantity;
     Quantity:value [a fhir:Decimal; fhir:value "176"^^xsd:decimal];
     Quantity:units [a fhir:String; fhir:value "g/L"];
     Quantity:system [a fhir:Uri; fhir:value <http://unitsofmeasure.org>];
     Quantity:code [a fhir:Code; fhir:value "g/L"]
  ].

fhir-rdf XSLT

Use

online
  1. use a generic XSLT service
  2. with the generated XSLT
  3. and some example instance data
  4. or hack the URL like http://services.w3.org/xslt?xslfile=https%3A%2F%2Fraw.githubusercontent.com%2Fw3c%2Fhcls-fhir-rdf%2Fmaster%2Fgeneric%2Ftransform.xsl&xmlfile=http%3A%2F%2Ffhir-dev.healthintersections.com.au%2Fopen%2FMedicationPrescription%2F124a6916-5d84-4b8c-b250-10cefb8e6e86&content-type=text%2Fplain&submit=transform

or use a specialized form

local
  1. download the XSLT and some example instance data, e.g. $(wget https://hl7-fhir.github.io/observation-example.xml)
  2. execute the XSLT via
    1. xsltproc (download or use a package manager to install libxml)
      xsltproc --stringparam literals nest --stringparam contained ref --stringparam reference inline --stringparam docParam "http://some.example/server/path/" transform.xsl observation-example.xml
    2. saxon
      @@fill in
parameters

The parameter defaults should align with the current side-by-side proposal.

  • docParam ./
    • ./: 
      <./> a fhir:MedicationPrescription.
      <./#med1> a fhir:Medication.
    • http://some.example/server/path/: 
      <http://some.example/server/path/> a fhir:MedicationPrescription.
      <http://some.example/server/path/#med1> a fhir:Medication.
  • contained ref|inline
    • ref:
      … fhir:contained <http://some.example/server/path/#med1>.
      <http://some.example/server/path/#med1> a fhir:Medication;
        fhir:Medication.id [ fhir:value "med1"^^fhir:id ];
        fhir:Medication.name [ fhir:value "Theophylline 200mg" ];
        fhir:Medication.code […].
    • inline:
      … fhir:contained [
        a fhir:Medication;
        fhir:Medication.id [ fhir:value "med1"^^fhir:id ];
        fhir:Medication.name [ fhir:value "Theophylline 200mg" ];
        fhir:Medication.code […];
      ];
  • reference ref|inline
    • ref:
      … fhir:MedicationPrescription.patient <http://fhir.healthintersections.com.au/open/Patient/d1>;
      <http://fhir.healthintersections.com.au/open/Patient/d1> fhir:Reference.display [ fhir:value "Peter Patient" ] .
    • inline:
      … fhir:MedicationPrescription.patient [
        a fhir:Reference;
        fhir:Reference.reference <http://fhir.healthintersections.com.au/open/Patient/d1>;
        fhir:Reference.display [ fhir:value "Peter Patient" ]
      ]
  • literals nest|inline
    • nest: fhir:Reference.display [ fhir:value "Peter Patient" ]
    • inline fhir:Reference.display "Peter Patient"

Development

  1. clone github repo
  2. cd generic
  3. $(make site) to download Josh Mandel's nightly FHIR build. This creates a directory site/ with files like allergyintolerance.profile.json
  4. $(make transform.xsl) creates a file transform.xsl which can be used to translate FHIR XML examples like allergyintolerance-example to XML.
    1. you will likely see that you need to install huTools:
      1. install pip (python's package manager); linux: $(sudo apt-get install python-pip), mac: ???, windows: ⸘⸮⁉
      2. install huTools: linux: $(sudo pip install huTools), mac: ???, windows: ⸘⸮⁉
  5. follow the instructions for runninng the XSLT locally

How it works

The process is driven by the Makefile.

  1. xslt_defs.xml: calls generate_xslt_defs.py to parse site/*.profile.xml and create monolithing XML resource definition xslt_defs.xml
  2. transform.xsl: concatonates a tiny top of an XSLT file head.xml with xslt_defs.xml and a more complex tail.xml to produce transform.xsl

tail.xml's match="/" calls the root templates which are either <xsl:template match="atom:feed" mode="root"> for packaging (needs to be updated to current encapsulation scheme) or or <xsl:template match="*" mode="root"> for everything else. The latter calls the workhorse ResourceRoot template which iteratively crawls through the FHIR Resource's XML matching it against elements in the tree from xslt_defs.xml. This includes a generic transformation for most properties and specific overrides:

Issues

        fhir:CodeableConcept.coding [
           a fhir:Coding;
           fhir:Coding.system <http://snomed.info/sct>;
           fhir:Coding.code "66493003"^^fhir:code;
        ];

vs.

        fhir:CodeableConcept.coding [
           a fhir:Coding;
           fhir:Coding.system [ fhir:value <http://snomed.info/sct> ];
           fhir:Coding.code [ fhir:value "66493003"^^fhir:code ];
        ];

OWL representation of FHIR Schema

derived ontology

Tasks

{ :someNarrative Narrative:status fhir:generated . }

=

{ :someNarrative Narrative:status [
      CodeableConcept:coding [
        fhir:system fhir:sysID,
        Coding:code "generated"
      ]
    ] .
}

Resources