Commit 4f74a4fb authored by rwm's avatar rwm
Browse files

Ontology supports integer/string/decimal/enum. Import to i2b2 working.

parent 01f4aa4e
......@@ -20,15 +20,4 @@
dwh:replaceValue :noValue
] .
# TODO use anonymous nodes
# TODO how to map negations (eg NO hypertension)
:FF.XXXX.example a dwh:Concept ;
dwh:valueType :YesNoEnum .
# TODO: need to implement labels for enum values
:YesNoEnum owl:oneOf (
[rdf:value "Y"^^xsd:string ; prefLabel "Ja"@de]
[rdf:value "N"^^xsd:string ; prefLabel "Nein"@de]
) .
......@@ -4,8 +4,8 @@
@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix dwh: <http://sekmi.de/histream/dwh#> .
@prefix : <http://sekmi.de/histream/skos/tests#> .
@prefix dwh: <http://sekmi.de/histream/dwh#> .
@prefix : <http://sekmi.de/histream/skos/tests#> .
: dc:title "HIStream concept ontology for testing".
......@@ -18,28 +18,35 @@
skos:narrower :TestStringConcept ;
skos:narrower :TestIntegerConcept ;
skos:narrower :TestDecimalConcept ;
skos:narrower :TestEnumConcept ;
dc:description "Top concept for test data" .
:TestEnumConcept a skos:Concept;
skos:inScheme :TestData;
dwh:restriction [ a owl:Restriction ;
owl:onProperty rdf:value;
owl:oneOf ([rdf:value "1"^^xsd:string; skos:prefLabel "1_de"@de; skos:prefLabel "1_en"@en ]
[rdf:value "2"^^xsd:string; skos:prefLabel "2_de"@de; skos:prefLabel "2_en"@en ])
] ;
dwh:restriction [ a owl:Restriction ;
owl:onProperty rdf:value;
owl:oneOf (
[rdf:value "1"^^xsd:string; skos:prefLabel "1_de"@de; skos:prefLabel "1_en"@en ]
[rdf:value "2"^^xsd:string; skos:prefLabel "2_de"@de; skos:prefLabel "2_en"@en ]
)
] ;
skos:prefLabel "Enum_label_de"@de;
skos:prefLabel "Enum_label_en"@en;
skos:notation "T:Enum" .
# skos:notation "Enum"^^:TestCS .
####### skos:notation "Enum"^^:TestCS .
dwh:IntegerRestriction a owl:Restriction ;
dwh:Integer a owl:Restriction ;
owl:onProperty rdf:value ;
owl:allValuesFrom xsd:integer .
dwh:String a owl:Restriction ;
owl:onProperty rdf:value ;
owl:allValuesFrom xsd:string .
:TestIntegerConcept a skos:Concept;
skos:inScheme :TestData ;
dwh:restriction dwh:IntegerRestriction ;
dwh:restriction dwh:Integer ;
skos:prefLabel "Integer_label_en"@en ;
skos:prefLabel "Integer_label_de"@de ;
dc:description "Description_de"@de ;
......@@ -48,22 +55,21 @@ dwh:IntegerRestriction a owl:Restriction ;
:TestStringConcept a skos:Concept;
skos:inScheme :TestData ;
dwh:valueType xsd:string ;
dwh:restriction dwh:String ;
skos:prefLabel "String_label_en"@en ;
skos:notation "T:type:str" .
:TestDecimalConcept a skos:Concept;
skos:inScheme :TestData ;
dwh:restriction [ a owl:Restriction ;
owl:onProperty rdf:value ;
owl:allValuesFrom [a rdfs:Datatype;
owl:onDatatype xsd:decimal;
owl:withRestrictions( [ xsd:minInclusive 200 ]
[ xsd:maxInclusive 400 ] )
]
] ;
# oder via rdfs:range? http://stackoverflow.com/questions/24531940/defining-datarange-expression-in-protege-for-a-data-type-property
# oder via owl:DataRange
# oder restriction owl:onProperty rdf:value
dwh:restriction [ a owl:Restriction ;
owl:onProperty rdf:value ;
owl:allValuesFrom[ a rdfs:Datatype;
owl:onDatatype xsd:decimal;
owl:withRestrictions(
[ xsd:minInclusive 200 ]
[ xsd:maxInclusive 400 ]
)
]
] ;
skos:prefLabel "Decimal_label_en"@en ;
skos:notation "T:type:dec" .
......@@ -4,6 +4,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.StringWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
......@@ -15,10 +16,17 @@ import java.util.Map;
import java.util.Properties;
import java.util.logging.Logger;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import de.sekmi.histream.Plugin;
import de.sekmi.histream.ontology.Concept;
import de.sekmi.histream.ontology.EnumValue;
import de.sekmi.histream.ontology.Ontology;
import de.sekmi.histream.ontology.OntologyException;
import de.sekmi.histream.ontology.ValueRestriction;
public class Import implements AutoCloseable{
private static final Logger log = Logger.getLogger(Import.class.getName());
......@@ -120,6 +128,83 @@ public class Import implements AutoCloseable{
insertConcept.executeUpdate();
insertConceptCount ++;
}
private String generateMetadataXML(ValueRestriction vr) throws XMLStreamException, OntologyException{
StringWriter xmlbuf = new StringWriter();
XMLOutputFactory xmlout = XMLOutputFactory.newInstance();
XMLStreamWriter xml = xmlout.createXMLStreamWriter(xmlbuf);
//xml.writeStartDocument();
xml.writeStartElement("ValueMetadata");
xml.writeStartElement("Version");
xml.writeCharacters("3.02");
xml.writeEndElement();
xml.writeStartElement("CreationDateTime");
xml.writeCharacters("10/07/2002 15:08:07"); // TODO use correct time
xml.writeEndElement();
// TestID, TestName,
EnumValue[] ev = vr.getEnumeration(locale);
if( ev != null ){
xml.writeStartElement("DataType");
xml.writeCharacters("Enum");
xml.writeEndElement();
xml.writeStartElement("Oktousevalues");
xml.writeCharacters("Y");
xml.writeEndElement();
xml.writeStartElement("EnumValues");
for( EnumValue v : ev ){
xml.writeStartElement("Val");
xml.writeAttribute("description",v.getPrefLabel());
xml.writeCharacters(v.getValue().toString());
xml.writeEndElement();
}
xml.writeEndElement();
}else{
String i2b2type;
QName type = vr.getType();
if( type != null ){
switch( type.getLocalPart() ){
case "integer":
case "int":
i2b2type = "Integer";
break;
case "float":
case "decimal":
i2b2type = "Float";
break;
case "string":
default:
i2b2type = "String";
}
}else{
// no type information
i2b2type = "String";
}
xml.writeStartElement("DataType");
xml.writeCharacters(i2b2type);
xml.writeEndElement();
// TODO other datatypes
// PosFloat, Float, PosInteger, Integer
// String, largestring
xml.writeStartElement("Oktousevalues");
xml.writeCharacters("Y");
xml.writeEndElement();
}
xml.writeEndDocument();
xml.close();
try {
xmlbuf.close();
} catch (IOException e) {
throw new XMLStreamException(e);
}
return xmlbuf.toString();
}
private void insertMeta(int level, String path_prefix, Concept concept, boolean accessRoot) throws SQLException, OntologyException{
insertMeta.setInt(1, level);
String label = concept.getPrefLabel(locale);
......@@ -145,6 +230,7 @@ public class Import implements AutoCloseable{
// c_visualattributes
Concept[] subConcepts = concept.getNarrower();
String visualAttr = (subConcepts.length == 0)?"LA":"FA";
// TODO MA for multiple items
insertMeta.setString(5, visualAttr);
// c_basecode
......@@ -163,10 +249,26 @@ public class Import implements AutoCloseable{
// TODO make sure, each concept_path is inserted only once
insertConceptDimension(path, label, conceptIds[0]);
// XXX support for multiple conceptIds can be hacked by appending a number to the path for each conceptid and insert each conceptid
// XXX see some concepts in i2b2 demodata religion with visualattributes M
}
// c_metadataxml
insertMeta.setString(7, null);
ValueRestriction vr = concept.getValueRestriction();
if( vr == null ){
insertMeta.setString(7, null);
}else{
// build metadata xml
// set value
try {
insertMeta.setString(7, generateMetadataXML(vr));
} catch (XMLStreamException e) {
// TODO log error
e.printStackTrace();
insertMeta.setString(7, null);
}
}
// c_dimcode (with concept_dimension.concept_path LIKE)
insertMeta.setString(8, path);
......@@ -257,6 +359,29 @@ public class Import implements AutoCloseable{
}
@Override
public void close() {
try {
dbMeta.close();
} catch (SQLException e) {
System.out.println("Error closing database connection");
e.printStackTrace();
}
try {
dbData.close();
} catch (SQLException e) {
System.out.println("Error closing database connection");
e.printStackTrace();
}
if( ontology != null )try {
ontology.close();
} catch (IOException e) {
System.err.println("Error closing ontology");
e.printStackTrace();
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public static void main(String args[])throws FileNotFoundException, IOException{
if( args.length != 2 ){
......@@ -338,25 +463,4 @@ public class Import implements AutoCloseable{
}
@Override
public void close() {
try {
dbMeta.close();
} catch (SQLException e) {
System.out.println("Error closing database connection");
e.printStackTrace();
}
try {
dbData.close();
} catch (SQLException e) {
System.out.println("Error closing database connection");
e.printStackTrace();
}
if( ontology != null )try {
ontology.close();
} catch (IOException e) {
System.err.println("Error closing ontology");
e.printStackTrace();
}
}
}
package de.sekmi.histream.i2b2;
import de.sekmi.histream.i2b2.ont.Import;
/**
* Demo to load ontology from Eclipse workspace
* @author marap1
*
*/
public class Demo {
public static void main(String args[]) throws Exception{
Import.main(new String[]{"../HIStream-i2b2/src/main/examples/skos-ontology.properties","../HIStream-i2b2/src/main/examples/i2b2-ont-import.properties"});
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment