Commit e7cedbd8 authored by R.W.Majeed's avatar R.W.Majeed

new project for export functionality

parent 743615a1
.settings/
.classpath
.project
target/
Algorithm
---------
1. Read all concept references. This can be actual concept codes
or wildcard concept codes.
2. The facts will be processed grouped by encounter. E.g. as
a list of all concepts for the given encounter.
If the patient or visit is different from the previous one
create new row in visit or encounter. Process all columns
which are NOT bound to any fact (not for fact tables which
are always bound to a fact).
3. For each fact:
3.1 Find all matching columns.
3.2
or
3. For each column:
3.1 Find all matching facts
\ No newline at end of file
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<name>HIStream : Export</name>
<description>
Export streams or collections of facts to table files
like CSV.
</description>
<groupId>de.sekmi.histream</groupId>
<artifactId>histream-export</artifactId>
<version>0.8-SNAPSHOT</version>
<parent>
<groupId>de.sekmi.histream</groupId>
<artifactId>histream</artifactId>
<version>0.8-SNAPSHOT</version>
</parent>
<build>
<plugins>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>de.sekmi.histream</groupId>
<artifactId>histream-core</artifactId>
<version>0.8-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package de.sekmi.histream.export;
import de.sekmi.histream.ObservationSupplier;
public class TableExportFactory {
public void export(ObservationSupplier supplier){
}
}
package de.sekmi.histream.export.config;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlTransient;
@XmlTransient
@XmlAccessorType(XmlAccessType.NONE)
@XmlSeeAlso({SequenceColumn.class, IdColumn.class})
public abstract class AbstractColumn {
/**
* Column header name
*/
@XmlAttribute(required=true)
String header;
/**
* Column value to use to indicate NA.
* This will be used if null values are
* encountered by the column. If not specified,
* the empty string {@code ''} will be used.
*/
@XmlAttribute
String na;
/**
* Prepare the column for the next row. This
* method is called once for every row.
* <p> The default implementation does nothing.</p>
*/
protected void prepareRow(){
}
/**
* Initializes the column. This method will be called
* only once and before any other method.
*/
protected void initialize(){
}
/**
* Get the column value for the current row.
* @return String value or {@code null} for NA.
*/
public abstract Object getValueString();
}
package de.sekmi.histream.export.config;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlTransient;
@XmlTransient
@XmlAccessorType(XmlAccessType.NONE)
public abstract class AbstractTable {
public abstract String[] getHeaders();
public abstract AbstractColumn getColumn(int index);
public abstract AbstractColumn getColumnByHeader(String header);
}
package de.sekmi.histream.export.config;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name="export")
public class ExportDescriptor {
@XmlElement
PatientTable patient;
@XmlElement
VisitTable visit;
@XmlElement(name="table")
FactTable[] tables;
}
package de.sekmi.histream.export.config;
public class FactTable {
}
package de.sekmi.histream.export.config;
/**
* Column which outputs intrinsic ID values. This
* column can only be used in {@link PatientTable} and
* {@link VisitTable}.
*
* @author R.W.Majeed
*
*/
public class IdColumn extends AbstractColumn{
@Override
public Object getValueString() {
// TODO Auto-generated method stub
return null;
}
}
package de.sekmi.histream.export.config;
import javax.xml.bind.annotation.XmlElement;
public class PatientTable {
@XmlElement(name="column")
AbstractColumn[] columns;
}
package de.sekmi.histream.export.config;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name="sequence")
public class SequenceColumn extends AbstractColumn{
@XmlElement(required=true)
String id;
@XmlElement
Long start;
long value;
protected SequenceColumn(){
}
public SequenceColumn(String id){
this.id = id;
}
@Override
protected void initialize(){
if( start != null ){
value = start;
}else{
value = 1;
}
}
@Override
public Object getValueString() {
return value;
// TODO increment value somewhere else
}
}
package de.sekmi.histream.export.config;
public class VisitTable {
}
/**
* Export configuration with JAXB annotations
*
*/
@javax.xml.bind.annotation.XmlSchema(
namespace="http://sekmi.de/ns/histream/export"
)
package de.sekmi.histream.export.config;
\ No newline at end of file
package de.sekmi.histream.export.config;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import org.junit.Test;
public class TestMarshal {
@Test
public void verifyMarshal() throws JAXBException{
ExportDescriptor e = new ExportDescriptor();
e.patient = new PatientTable();
e.patient.columns = new AbstractColumn[2];
e.patient.columns[0] = new IdColumn();
e.patient.columns[0].header = "pid";
e.patient.columns[1] = new SequenceColumn("seq1");
e.patient.columns[1].header = "seq";
JAXBContext j = JAXBContext.newInstance(ExportDescriptor.class);
Marshaller m = j.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
m.marshal(e, System.out);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<export xmlns="http://sekmi.de/ns/histream/export">
<patient>
<column header="pid" type="id"/>
<column header="seq" type="sequence">
<id>seq1</id>
</column>
</patient>
<visit>
<column header="pid" type="patient-ref"/>
<column header="visit" type="id"/>
<!-- concepts for the visit table must occur only once
per visit and may not repeat -->
<column header="start" type="attribute">
<property>start</property>
</column>
<!-- What is better? -->
<!-- (a) First column, then concepts with value -->
<column header="diagnostik_labort_ts" na="NULL" type="fact">
<concept code="LOINC:26436-6"/>
<concept code="LOINC:26436-6:NEG"/>
<value type="script">
<eval>fact.conceptId.substring(6)</eval>
</value>
</column>
<!-- (b) first concepts then columns with value -->
<group>
<concept code="LOINC:26436-6"/>
<concept code="LOINC:26436-6:NEG"/>
<column header="lab_ts" type="attribute">
<attribute>start</attribute>
</column>
<!-- We want this:
6:NEG -> not tested
6/mod=OPB -> tested non pathological
6/mod=PB -> tested pathological
-->
<column header="lab_ergebnis" type="attribute">
<modifier>PB</modifier>
<attribute>start</attribute>
</column>
</group>
</visit>
<table id="diagnosen">
<!-- makes more sense for fact tables to specify
the list of concepts first. -->
<concept wildcard="ICD10:*"/>
<concept code="ICD9:123"/>
<column header="pid" type="patient-ref"/>
<column header="visit" type="visit-ref"/>
<column header="start" type="attribute">
<attribute>start</attribute>
</column>
<column header="primary" type="attribute" na="nein">
<modifier>fuehrend</modifier>
<!-- if a modifier element is provided, the property
will use the context of that modifier -->
<constant-value>ja</constant-value>
</column>
<column header="text" type="attribute">
<modifier>originalText</modifier>
<property>value</property>
</column>
<!-- reference sequence from patient -->
<column header="seq1" type="sequence">
<sequence ref="seq1"/>
</column>
</table>
</export>
\ No newline at end of file
......@@ -57,6 +57,8 @@
<!--<module>histream-hl7</module>-->
<module>histream-skos</module>
<module>histream-import</module>
<module>histream-export</module>
<module>histream-js</module>
<module>i2b2-integration-tests</module>
<module>distribution</module>
</modules>
......
Markdown is supported
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