W3C logo
slanted W3C logo

RDF geeking for Life Sciences

W3C Semantic Web in Health Care and Life Sciences.


Eric Prud'hommeaux, Sanitation Engineer.
URL: http://tinyurl.com/ybdsnme
Last modified: $Date: 2009/10/05 12:22:07 $
Creative Commons License This work is licensed under a Creative Commons Attribution 3.0 License, with attribution to W3C.

Valid XHTML + RDFa

RDF: fabric of assertions about people, ...

... medicine, ...

... life sciences, ...

... in one universe.

Who is HCLS?

W3C Semantic Web Health Care and Life Sciences Interest Group.

90+ members from industry and academia.

a couple KBs (order 400 triples)

papers

Workshops

Ontology mapping code.

6 Task Forces

Other Projects: Clinical Decision Support...

HCLS KB

A Knowledgebase for Neuroscience

Built by Neurocommons and the HCLS BioRDF task force.

Precise answers to complex questions:

What proteins are associated with pyramidal neurons
AND are involved in signal transduction.

Integrate Databases

Real Query

HCLS demo #2 query: SPARQL query over MeSH, PubMed, Entrez Gene, GO

Linking Open Drug Data

Evaluating LODD sources

Clinical Observations Interoperability

Real Hospital Database

Real Hospital Database as RDF

... Sharable RDF

   PREFIX :mydb <http://cityhospital.example/dbs>
CONSTRUCT { ?o a               study:SubjectObservation .
            ?o study:subject   ?p .
            ?o study:clinician ?d .
            ?d :foaf:name ?dName }

    WHERE { ?o mydb:patient ?p .
            ?o mydb:doctor  ?d .
            ?d mydb:name    ?dName }

Query Transformation

PREFIX db: <…>
SELECT ?o ?d
 WHERE {
   ?o db:onPatient <Bob> .
   ?o db:byDoctor ?d .
 }

PREFIX db: <…>
SELECT observations... doctors...
  FROM observations, 
   patients ON id=observations.patient ...
   WHERE patients.name = "Bob"
 }

Scientific Discourse ...

Scientific Discourse expresses hypotheses

Scientists use this!

SWAN screenshot

Terminology

Importing terms into Semantic Web.

Translational Medicine Ontology

Requires data from bench to bedside.

Spans health care and life sciences

Models drug development lifecycle

Unification needed in lots of places

a course view of DBpedia

LOD cloud

a course view of LODD

LODD cloud

Inference

Inferring types

Inferring types

OWL - inferring lots of stuff

Introduction to OWL

OWL consistency rules

OWL type inference

OWL identity inference

OWL expression

OWL restrictions

OWL restrictions

OWL restrictions

RDF Formats

Turtle Example: Blood Pressure






<encounter7> edns:patient <patient3> .

<patient3>   r:type galen:Patient ;
             foaf:family_name "Levin" ;
             foaf:firstName "Henry" .



      

Turtle Example: Blood Pressure






<encounter7> edns:patient <patient3> ;
             edns:screeningBP <s20090714c> .
<patient3>   r:type galen:Patient ;
             foaf:family_name "Levin" ;
             foaf:firstName "Henry" .
<s20090714c> dc:date "2009-07-14T18:23"^^xsd:dateTime ;
             edns:systolic "132"^^edns:mmHg ;
             edns:diastolic "86"^^edns:mmHg .
             
      

Turtle Example: Blood Pressure

@prefix edns: <http://www.loa-cnr.it/ontologies/ExtendedDnS.owl#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix galen: <http://www.co-ode.org/ontologies/galen#> .
@prefix snomed: <http://termhost.example/SNOMED/> .

<encounter7> edns:patient <patient3> ;
             edns:screeningBP <s20090714c> .
<patient3>   r:type galen:Patient ;
             foaf:family_name "Levin" ;
             foaf:firstName "Henry" .
<s20090714c> dc:date "2009-07-14T18:23"^^xsd:dateTime ;
             edns:systolic "132"^^edns:mmHg ;
             edns:diastolic "86"^^edns:mmHg .
             

Turtle Example: Blood Pressure

@prefix edns: <http://www.loa-cnr.it/ontologies/ExtendedDnS.owl#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix galen: <http://www.co-ode.org/ontologies/galen#> .
@prefix snomed: <http://termhost.example/SNOMED/> .

<encounter7> edns:patient <patient3> ;
             edns:screeningBP <s20090714c> .
<patient3>   r:type galen:Patient ;
             foaf:family_name "Levin" ;
             foaf:firstName "Henry" .
<s20090714c> dc:date "2009-07-14T18:23"^^xsd:dateTime ;
             edns:systolic "132"^^edns:mmHg ;
             edns:diastolic "86"^^edns:mmHg ;
             edns:posture snomed:_163035008 . # SNOMED:sitting

RDF/XML Example: Blood Pressure

<rdf:RDF xmlns:edns="http://www.loa-cnr.it/ontologies/ExtendedDnS.owl#"
	 xmlns:foaf: "http://xmlns.com/foaf/0.1/" .
	 xmlns:galen: "http://www.co-ode.org/ontologies/galen#" .
	 xmlns:snomed: "http://termhost.example/SNOMED/">
<rdf:Description rdf:about="encounter7">
  <edns:patient rdf:resource="patient3"/>
  <edns:screeningBP>s20090714c</edns:screeningBP>
</rdf:Description>
<galen:Patient rdf:about="patient3" foaf:family_name="Levin" foaf:firstName="Henry">
<rdf:Description rdf:about="s20090714c">
  <dc:date xsi:dt="http://www.w3.org/2001/XMLSchemadateTime">2009-07-14T18:23</dc:date>
  <edns:systolic xsi:dt="http://www.loa-cnr.it/ontologies/ExtendedDnS.owl#mmHg">132</edns:systolic>
  <edns:diastolic xsi:dt="http://www.loa-cnr.it/ontologies/ExtendedDnS.owl#mmHg">86</edns:systolic>
  <edns:posture rdf:resource="http://termhost.example/SNOMED/_163035008</edns:posture> <!-- SNOMED:sitting -->
</rdf:Description>

RDFa

RDFa Example: Chemicals

InChI is a textual identifier for chemical substances. Consider inchi.html:

<table>
<tr>
  <th>Familiar name</th><th>InChI</th>
</tr><tr>
  <td>Methane</td>
  <td about="http://example.org/methane" property="chem:inchi"
      xmlns:chem="http://www.blueobelisk.org/chemistryblogs/">
    InChI=1/CH4/h1H4
  </td>
...

This RDFa encodes the single RDF triple:

<http://example.org/methane> chem:inchi "InChI=1/CH4/h1H4" .

RDFa: The Gory Details

attributespecifiesattributespecifies
@aboutsubjects @propertypredicate relating subject to literal content
@hrefobjects, clickable @relpredicate relating subject to resources (@href, @src)
@srcobjects, embedded @revpredicate relating resources to subject in reverse
@resourceobjects, not clickable @contentObject of triple (instead of element content)
@instanceofRDF types @datatypeliteral values' data types

For more, see the RDFa primer or the RDFa specification.

Using RDFa: In context

operator on inchi data in RDFa

See inchi.html.

Introduction to GRDDL

Using GRDDL to get RDF from XML, XHTML

XML data

<?xml version="1.0"?>
<ClinicalDocument transformation="hl7-rim-to-pomr.xslt">
  <recordTarget>
    <patientRole>
      <patientPatient>
	<name>
	  <given>Henry</given>
	  <family>Levin</family>
	</name>
	<administrativeGenderCode code="M"/>
	<birthTime value="19320924"/>
      </patientPatient>
    </patientRole>
  </recordTarget>
  <component>
    <StructuredBody>
      <Observation>
	<code displayName="Cuff blood pressure"/>
	<effectiveTime value="200004071430"/>
	<targetSiteCode displayName="Left arm"/>
	<entryRelationship typeCode="COMP">
	  <Observation>
	    <effectiveTime value="200004071530"/>
	    <value value="132" unit="mm[Hg]"/>
	  </Observation>
	</entryRelationship>
      </Observation>
      <Observation>
	<code displayName="Cuff blood pressure"/>
	<effectiveTime value="200004071530"/>
	<targetSiteCode displayName="Left arm"/>
	<entryRelationship typeCode="COMP">
	  <Observation>
	    <code displayName="Systolic BP"/>
	    <effectiveTime value="200004071530"/>
	    <value value="135" unit="mm[Hg]"/>
	  </Observation>
	</entryRelationship>
	<entryRelationship typeCode="COMP">
	  <Observation>
	    <code displayName="Diastolic BP"/>
	    <effectiveTime value="200004071530"/>
	    <value value="88" unit="mm[Hg]"/>
	  </Observation>
	</entryRelationship>
      </Observation>
    </StructuredBody>
  </component>
</ClinicalDocument>

Mapped to RDF

[unrendered SVG image of HL7 data in RDF]

XSLT

<xsl:template match="rim:ClinicalDocument[rim:recordTarget/
                        rim:patientRole/rim:patientPatient]">
  <cpr:patient-record>
    <xsl:apply-templates select="rim:effectiveTime"/>
    <xsl:apply-templates select="rim:recordTarget/
                        rim:patientRole/rim:patientPatient"/>
    <xsl:for-each select="rim:author/
                      rim:assignedAuthor/rim:assignedPerson">
      <foaf:maker>
        <foaf:Person>
          <xsl:apply-templates select="rim:name"/>
        </foaf:Person>
      </foaf:maker>
    </xsl:for-each>
    <xsl:apply-templates select="rim:component"/>
  </cpr:patient-record>
</xsl:template>

<xsl:template match="rim:name/rim:family">
  <foaf:family_name><xsl:value-of select="."/></foaf:family_name>
</xsl:template>

<xsl:template match="rim:name/rim:given">
  <foaf:firstName><xsl:value-of select="."/></foaf:firstName>
</xsl:template>

<xsl:template match="rim:patientPatient">
  <edns:about>
    <galen:Patient>
      <xsl:apply-templates select="rim:name"/>
    </galen:Patient>
  </edns:about>
</xsl:template>

XSLT

<xsl:template match="rim:ClinicalDocument[rim:recordTarget/
                        rim:patientRole/rim:patientPatient]">
  <cpr:patient-record>
    <xsl:apply-templates select="rim:effectiveTime"/>
    <xsl:apply-templates select="rim:recordTarget/
                        rim:patientRole/rim:patientPatient"/>
    <xsl:for-each select="rim:author/
                      rim:assignedAuthor/rim:assignedPerson">
      <foaf:maker>
        <foaf:Person>
          <xsl:apply-templates select="rim:name"/>
        </foaf:Person>
      </foaf:maker>
    </xsl:for-each>
    <xsl:apply-templates select="rim:component"/>
  </cpr:patient-record>
</xsl:template>
<xsl:template match="rim:name/rim:family">
  <foaf:family_name><xsl:value-of select="."/></foaf:family_name>
</xsl:template>

<xsl:template match="rim:name/rim:given">
  <foaf:firstName><xsl:value-of select="."/></foaf:firstName>
</xsl:template>

<xsl:template match="rim:patientPatient">
  <edns:about>
    <galen:Patient>
      <xsl:apply-templates select="rim:name"/>
    </galen:Patient>
  </edns:about>
</xsl:template>

XSLT

<xsl:template match="rim:ClinicalDocument[rim:recordTarget/
                        rim:patientRole/rim:patientPatient]">
  <cpr:patient-record>
    <xsl:apply-templates select="rim:effectiveTime"/>
    <xsl:apply-templates select="rim:recordTarget/
                        rim:patientRole/rim:patientPatient"/>
    <xsl:for-each select="rim:author/
                      rim:assignedAuthor/rim:assignedPerson">
      <foaf:maker>
        <foaf:Person>
          <xsl:apply-templates select="rim:name"/>
        </foaf:Person>
      </foaf:maker>
    </xsl:for-each>
    <xsl:apply-templates select="rim:component"/>
  </cpr:patient-record>
</xsl:template>
<xsl:template match="rim:name/rim:family">
  <foaf:family_name><xsl:value-of select="."/></foaf:family_name>
</xsl:template>

<xsl:template match="rim:name/rim:given">
  <foaf:firstName><xsl:value-of select="."/></foaf:firstName>
</xsl:template>
<xsl:template match="rim:patientPatient">
  <edns:about>
    <galen:Patient>
      <xsl:apply-templates select="rim:name"/>
    </galen:Patient>
  </edns:about>
</xsl:template>

XSLT

<xsl:template match="rim:ClinicalDocument[rim:recordTarget/
                        rim:patientRole/rim:patientPatient]">
  <cpr:patient-record>
    <xsl:apply-templates select="rim:effectiveTime"/>
    <xsl:apply-templates select="rim:recordTarget/
                        rim:patientRole/rim:patientPatient"/>
    <xsl:for-each select="rim:author/
                      rim:assignedAuthor/rim:assignedPerson">
      <foaf:maker>
        <foaf:Person>
          <xsl:apply-templates select="rim:name"/>
        </foaf:Person>
      </foaf:maker>
    </xsl:for-each>
    <xsl:apply-templates select="rim:component"/>
  </cpr:patient-record>
</xsl:template>

<xsl:template match="rim:name/rim:family">
  <foaf:family_name><xsl:value-of select="."/></foaf:family_name>
</xsl:template>

<xsl:template match="rim:name/rim:given">
  <foaf:firstName><xsl:value-of select="."/></foaf:firstName>
</xsl:template>
<xsl:template match="rim:patientPatient">
  <edns:about>
    <galen:Patient>
      <xsl:apply-templates select="rim:name"/>
    </galen:Patient>
  </edns:about>
</xsl:template>

XSLT courtesy of Chimezie Ogbuji

GRDDLing HTML

GRDDL can extract RDF from both XML and (X)HTML.

<Observation>
  <effectiveTime value="20090403T12:34+0400">
    <title>Clinical Study 8B1a: Patient BP</title>
    <value value=86 unites="mm[Hg]"/>
  </effectiveTime>
</Observation>
<html>
  <head profile="http://www.w3.org/2003/g/data-view">
    <title>Clinical Study 8B1a: Patient BP</title>
    <link rel="transformation" href="bp-html-to-pomr.xslt" />
  </head>
  ...

GRDDL Mechanics

Content publisher provides XML or XHTML document that does one of:

GRDDL Resources

Even relational data ...

[unrendered SVG image of HL7 data in a relational database]

... produces graphs.

[unrendered SVG image of HL7 data in RDF]

Advanced SPARQL

GRAPH constraints

SPARQL lets us query different RDF graphs in a single query. Consider movie reviews:

Result forms

3 types of queries:

SELECT and ASK results can be returned as XML or JSON. CONSTRUCT and DESCRIBE results can be returned via any RDF serialization (e.g. RDF/XML or Turtle).

SPARQL Protocol Mechanics

The SPARQL Protocol is a simple method for asking and answering SPARQL queries over HTTP. A SPARQL URL is built from three parts:

  1. The URL of a SPARQL endpoint (e.g. http://example.org/sparql)
  2. (Optional, as part of the query string) The graphs to be queried against (e.g. named-graph-uri=http://example.org/reviews/ebert
  3. (As part of the query string) The query itself (e.g. query=SELECT...)
http://example.org/sparql?named-graph-uri=http%3A%2F%2Fexample.orgm%2F
reviews%2Febert&query=SELECT+%3Freview_graph+WHERE+%7B%0D%0A++GRAPH+%3Frev
iew_graph+%7B%0D%0A+++++%3Freview+rev%3Arating+10+.%0D%0A++%7D%0D%0A%7D

SPARQL Resources

Internationalization (i18n)

Collaboration

We want your help

join per <http://www.w3.org/2001/sw/hcls/#Participation>.