You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ctakes.apache.org by se...@apache.org on 2018/03/05 15:09:59 UTC

svn commit: r1825907 [3/4] - in /ctakes/trunk: ctakes-core/src/main/java/org/apache/ctakes/core/ae/ ctakes-core/src/main/java/org/apache/ctakes/core/cc/html/ ctakes-core/src/main/java/org/apache/ctakes/core/cr/ ctakes-core/src/main/java/org/apache/ctak...

Modified: ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/cc/FhirDocComposer.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/cc/FhirDocComposer.java?rev=1825907&r1=1825906&r2=1825907&view=diff
==============================================================================
--- ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/cc/FhirDocComposer.java (original)
+++ ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/cc/FhirDocComposer.java Mon Mar  5 15:09:58 2018
@@ -1,142 +1,177 @@
-package org.apache.ctakes.fhir.cc;
-
-
-import org.apache.ctakes.core.util.EssentialAnnotationUtil;
-import org.apache.ctakes.fhir.resource.*;
-import org.apache.ctakes.fhir.util.NoteSpecs;
-import org.apache.ctakes.typesystem.type.relation.BinaryTextRelation;
-import org.apache.ctakes.typesystem.type.relation.RelationArgument;
-import org.apache.ctakes.typesystem.type.textsem.IdentifiedAnnotation;
-import org.apache.ctakes.typesystem.type.textspan.Segment;
-import org.apache.log4j.Logger;
-import org.apache.uima.fit.util.JCasUtil;
-import org.apache.uima.jcas.JCas;
-import org.apache.uima.jcas.tcas.Annotation;
-import org.hl7.fhir.dstu3.model.Basic;
-import org.hl7.fhir.dstu3.model.Bundle;
-import org.hl7.fhir.dstu3.model.Reference;
-import org.hl7.fhir.dstu3.model.Resource;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * @author SPF , chip-nlp
- * @version %I%
- * @since 12/15/2017
- */
-final public class FhirDocComposer {
-
-   static private final Logger LOGGER = Logger.getLogger( "FhirDocComposer" );
-
-   static private final String SIMPLE_SECTION = "SIMPLE_SEGMENT";
-
-   private FhirDocComposer() {
-   }
-
-
-   static public Bundle composeDocFhir( final JCas jCas ) {
-      final NoteSpecs noteSpecs = new NoteSpecs( jCas );
-      // creators
-      final FhirResourceCreator<IdentifiedAnnotation, Basic> iaCreator = new IdentifiedAnnotationBasicCreator();
-      final FhirResourceCreator<Annotation, Basic> aCreator = new AnnotationBasicCreator();
-      final FhirResourceCreator<Segment, Basic> sectionCreator = new SectionBasicCreator();
-      // essential types
-      final Map<Segment, Collection<IdentifiedAnnotation>> sectionAnnotationMap
-            = JCasUtil.indexCovered( jCas, Segment.class, IdentifiedAnnotation.class );
-      final Collection<Basic> sections = new ArrayList<>( sectionAnnotationMap.size() );
-      final Map<IdentifiedAnnotation, Collection<Integer>> markableCorefs = EssentialAnnotationUtil.createMarkableCorefs( jCas );
-      final Collection<IdentifiedAnnotation> requiredAnnotations = EssentialAnnotationUtil.getRequiredAnnotations( jCas, markableCorefs );
-      // Create map of annotations to Fhir Basics.
-      final Map<IdentifiedAnnotation, Basic> annotationBasics = new HashMap<>();
-      for ( Map.Entry<Segment, Collection<IdentifiedAnnotation>> sectionAnnotations : sectionAnnotationMap.entrySet() ) {
-         final Segment segment = sectionAnnotations.getKey();
-         final String segmentId = segment.getId();
-         final Basic section = sectionCreator.createResource( jCas, sectionAnnotations.getKey(), noteSpecs );
-         if ( !segmentId.isEmpty() && !segmentId.equals( SIMPLE_SECTION ) ) {
-            sections.add( section );
-         }
-         final Reference sectionRef = new Reference( section );
-         for ( IdentifiedAnnotation annotation : sectionAnnotations.getValue() ) {
-            if ( !requiredAnnotations.contains( annotation ) ) {
-               continue;
-            }
-            final Basic basic = iaCreator.createResource( jCas, annotation, noteSpecs );
-            if ( !segmentId.isEmpty() && !segmentId.equals( SIMPLE_SECTION ) ) {
-               basic.addExtension( FhirElementFactory.createSectionExtension( sectionRef ) );
-            }
-            final Collection<Integer> corefs = markableCorefs.get( annotation );
-            if ( corefs != null ) {
-               corefs.stream()
-                     .map( FhirElementFactory::createCorefIndex )
-                     .forEach( basic::addExtension );
-            }
-            annotationBasics.put( annotation, basic );
-         }
-      }
-      // Add relations as reference extensions.
-      final Map<org.apache.uima.jcas.tcas.Annotation, Basic> simpleAnnotationBasics = new HashMap<>();
-      addRelations( jCas, noteSpecs, aCreator, annotationBasics, simpleAnnotationBasics );
-      // Create a Bundle
-      final Bundle bundle = new BundleCreator().createResource( jCas, null, noteSpecs );
-      bundle.addEntry( new Bundle.BundleEntryComponent().setResource( PractitionerCtakes.getPractitioner() ) );
-      addBundleResources( bundle, noteSpecs.getSubjects() );
-      addBundleResources( bundle, sections );
-      addBundleResources( bundle, annotationBasics.values() );
-      addBundleResources( bundle, simpleAnnotationBasics.values() );
-      return bundle;
-   }
-
-   static private void addBundleResources( final Bundle bundle, final Collection<? extends Resource> resources ) {
-      resources.stream()
-            .map( r -> new Bundle.BundleEntryComponent().setResource( r ) )
-            .forEach( bundle::addEntry );
-   }
-
-   static private void addRelations( final JCas jCas,
-                                     final NoteSpecs noteSpecs,
-                                     final FhirResourceCreator<Annotation, Basic> aCreator,
-                                     final Map<IdentifiedAnnotation, Basic> annotationBasics,
-                                     final Map<org.apache.uima.jcas.tcas.Annotation, Basic> simpleBasics ) {
-      final Collection<BinaryTextRelation> relations = JCasUtil.select( jCas, BinaryTextRelation.class );
-      for ( BinaryTextRelation relation : relations ) {
-         final RelationArgument arg1 = relation.getArg1();
-         final org.apache.uima.jcas.tcas.Annotation source = arg1.getArgument();
-         Basic basicSource;
-         if ( source instanceof IdentifiedAnnotation ) {
-            basicSource = annotationBasics.get( (IdentifiedAnnotation) source );
-         } else {
-            basicSource = getSimpleBasic( jCas, source, noteSpecs, aCreator, simpleBasics );
-         }
-         final RelationArgument arg2 = relation.getArg2();
-         final org.apache.uima.jcas.tcas.Annotation target = arg2.getArgument();
-         Basic basicTarget;
-         if ( target instanceof IdentifiedAnnotation ) {
-            basicTarget = annotationBasics.get( (IdentifiedAnnotation) target );
-         } else {
-            basicTarget = getSimpleBasic( jCas, target, noteSpecs, aCreator, simpleBasics );
-         }
-         final String type = relation.getCategory();
-         basicSource.addExtension( FhirElementFactory.createRelation( type, basicTarget ) );
-      }
-   }
-
-
-   static private Basic getSimpleBasic( final JCas jCas,
-                                        final org.apache.uima.jcas.tcas.Annotation annotation,
-                                        final NoteSpecs noteSpecs,
-                                        final FhirResourceCreator<Annotation, Basic> aCreator,
-                                        final Map<org.apache.uima.jcas.tcas.Annotation, Basic> simpleBasics ) {
-      final Basic basic = simpleBasics.get( annotation );
-      if ( basic != null ) {
-         return basic;
-      }
-      final Basic newBasic = aCreator.createResource( jCas, annotation, noteSpecs );
-      simpleBasics.put( annotation, newBasic );
-      return newBasic;
-   }
-
-
-}
+package org.apache.ctakes.fhir.cc;
+
+
+import org.apache.ctakes.core.util.EssentialAnnotationUtil;
+import org.apache.ctakes.fhir.element.FhirElementFactory;
+import org.apache.ctakes.fhir.resource.*;
+import org.apache.ctakes.fhir.util.FhirNoteSpecs;
+import org.apache.ctakes.typesystem.type.relation.BinaryTextRelation;
+import org.apache.ctakes.typesystem.type.relation.RelationArgument;
+import org.apache.ctakes.typesystem.type.textsem.IdentifiedAnnotation;
+import org.apache.ctakes.typesystem.type.textspan.Segment;
+import org.apache.log4j.Logger;
+import org.apache.uima.fit.util.JCasUtil;
+import org.apache.uima.jcas.JCas;
+import org.apache.uima.jcas.tcas.Annotation;
+import org.hl7.fhir.dstu3.model.*;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Creates a complete fhir bundle for a note.
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 12/15/2017
+ */
+final public class FhirDocComposer {
+
+   static private final Logger LOGGER = Logger.getLogger( "FhirDocComposer" );
+
+   static private final String SIMPLE_SECTION = "SIMPLE_SEGMENT";
+
+   private FhirDocComposer() {
+   }
+
+   /**
+    * @param jCas         ye olde ...
+    * @param practitioner fhir practitioner.  Usually the default "ctakes" practitioner.
+    * @return a complete fhir bundle for a note.
+    */
+   static public Bundle composeDocFhir( final JCas jCas, final FhirPractitioner practitioner ) {
+      final FhirNoteSpecs noteSpecs = new FhirNoteSpecs( jCas );
+      // creators
+      final CompositionCreator compositionCreator = new CompositionCreator();
+      final FhirResourceCreator<Segment, Basic> sectionCreator = new SectionBasicCreator();
+      final FhirResourceCreator<IdentifiedAnnotation, Basic> iaCreator = new IdentifiedAnnotationBasicCreator();
+      final FhirResourceCreator<Annotation, Basic> aCreator = new AnnotationBasicCreator();
+      // essential types
+      final Map<Segment, Collection<IdentifiedAnnotation>> sectionAnnotationMap
+            = JCasUtil.indexCovered( jCas, Segment.class, IdentifiedAnnotation.class );
+      final Collection<Basic> sections = new ArrayList<>( sectionAnnotationMap.size() );
+      final Map<IdentifiedAnnotation, Collection<Integer>> markableCorefs = EssentialAnnotationUtil.createMarkableCorefs(
+            jCas );
+      final Collection<IdentifiedAnnotation> requiredAnnotations = EssentialAnnotationUtil.getRequiredAnnotations( jCas,
+            markableCorefs );
+      // Create map of annotations to Fhir Basics.
+      final Map<IdentifiedAnnotation, Basic> annotationBasics = new HashMap<>();
+      for ( Map.Entry<Segment, Collection<IdentifiedAnnotation>> sectionAnnotations : sectionAnnotationMap.entrySet() ) {
+         final Segment segment = sectionAnnotations.getKey();
+         final String segmentId = segment.getId();
+         final Basic section = sectionCreator.createResource( jCas, sectionAnnotations.getKey(), practitioner,
+               noteSpecs );
+         if ( !segmentId.isEmpty() && !segmentId.equals( SIMPLE_SECTION ) ) {
+            sections.add( section );
+         }
+         final Reference sectionRef = new Reference( section );
+         for ( IdentifiedAnnotation annotation : sectionAnnotations.getValue() ) {
+            if ( !requiredAnnotations.contains( annotation ) ) {
+               continue;
+            }
+            final Basic basic = iaCreator.createResource( jCas, annotation, practitioner, noteSpecs );
+            if ( !segmentId.isEmpty() && !segmentId.equals( SIMPLE_SECTION ) ) {
+               basic.addExtension( FhirElementFactory.createSectionExtension( sectionRef ) );
+            }
+            final Collection<Integer> corefs = markableCorefs.get( annotation );
+            if ( corefs != null ) {
+               corefs.stream()
+                     .map( FhirElementFactory::createCorefIndex )
+                     .forEach( basic::addExtension );
+            }
+            annotationBasics.put( annotation, basic );
+         }
+      }
+      // Add relations as reference extensions.
+      final Map<Annotation, Basic> simpleAnnotationBasics = new HashMap<>();
+      addRelations( jCas, practitioner, noteSpecs, aCreator, annotationBasics, simpleAnnotationBasics );
+      // Create a Bundle
+      final Composition composition = compositionCreator.createResource( jCas, null, practitioner, noteSpecs );
+      final Bundle bundle = new BundleCreator().createResource( jCas, null, practitioner, noteSpecs );
+      bundle.addEntry( new Bundle.BundleEntryComponent().setResource( composition ) );
+      bundle.addEntry( new Bundle.BundleEntryComponent().setResource( practitioner.getPractitioner() ) );
+      addBundleResources( bundle, noteSpecs.getSubjects() );
+      addBundleResources( bundle, sections );
+      addBundleResources( bundle, annotationBasics.values() );
+      addBundleResources( bundle, simpleAnnotationBasics.values() );
+      return bundle;
+   }
+
+   /**
+    * Add all of the given resources to the given bundle.
+    *
+    * @param bundle    -
+    * @param resources -
+    */
+   static private void addBundleResources( final Bundle bundle, final Collection<? extends Resource> resources ) {
+      resources.stream()
+            .map( r -> new Bundle.BundleEntryComponent().setResource( r ) )
+            .forEach( bundle::addEntry );
+   }
+
+   /**
+    * Link fhir object ids according to ctakes relations.
+    * @param jCas ye olde ...
+    * @param practitioner -
+    * @param noteSpecs -
+    * @param aCreator -
+    * @param annotationBasics -
+    * @param simpleBasics -
+    */
+   static private void addRelations( final JCas jCas,
+                                     final FhirPractitioner practitioner,
+                                     final FhirNoteSpecs noteSpecs,
+                                     final FhirResourceCreator<Annotation, Basic> aCreator,
+                                     final Map<IdentifiedAnnotation, Basic> annotationBasics,
+                                     final Map<Annotation, Basic> simpleBasics ) {
+      final Collection<BinaryTextRelation> relations = JCasUtil.select( jCas, BinaryTextRelation.class );
+      for ( BinaryTextRelation relation : relations ) {
+         final RelationArgument arg1 = relation.getArg1();
+         final Annotation source = arg1.getArgument();
+         Basic basicSource;
+         if ( source instanceof IdentifiedAnnotation ) {
+            basicSource = annotationBasics.get( (IdentifiedAnnotation)source );
+         } else {
+            basicSource = getSimpleBasic( jCas, source, practitioner, noteSpecs, aCreator, simpleBasics );
+         }
+         final RelationArgument arg2 = relation.getArg2();
+         final Annotation target = arg2.getArgument();
+         Basic basicTarget;
+         if ( target instanceof IdentifiedAnnotation ) {
+            basicTarget = annotationBasics.get( (IdentifiedAnnotation)target );
+         } else {
+            basicTarget = getSimpleBasic( jCas, target, practitioner, noteSpecs, aCreator, simpleBasics );
+         }
+         final String type = relation.getCategory();
+         basicSource.addExtension( FhirElementFactory.createRelation( type, basicTarget ) );
+      }
+   }
+
+   /**
+    *
+    * @param jCas ye olde ...
+    * @param annotation -
+    * @param practitioner -
+    * @param noteSpecs -
+    * @param aCreator -
+    * @param simpleBasics -
+    * @return fhir Basic object for the given annotation.
+    */
+   static private Basic getSimpleBasic( final JCas jCas,
+                                        final Annotation annotation,
+                                        final FhirPractitioner practitioner,
+                                        final FhirNoteSpecs noteSpecs,
+                                        final FhirResourceCreator<Annotation, Basic> aCreator,
+                                        final Map<Annotation, Basic> simpleBasics ) {
+      final Basic basic = simpleBasics.get( annotation );
+      if ( basic != null ) {
+         return basic;
+      }
+      final Basic newBasic = aCreator.createResource( jCas, annotation, practitioner, noteSpecs );
+      simpleBasics.put( annotation, newBasic );
+      return newBasic;
+   }
+
+
+}

Added: ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/cc/FhirJsonWriter.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/cc/FhirJsonWriter.java?rev=1825907&view=auto
==============================================================================
--- ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/cc/FhirJsonWriter.java (added)
+++ ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/cc/FhirJsonWriter.java Mon Mar  5 15:09:58 2018
@@ -0,0 +1,63 @@
+package org.apache.ctakes.fhir.cc;
+
+import ca.uhn.fhir.context.FhirContext;
+import ca.uhn.fhir.parser.IParser;
+import org.apache.ctakes.core.pipeline.PipeBitInfo;
+import org.apache.ctakes.fhir.resource.PractitionerCtakes;
+import org.apache.log4j.Logger;
+import org.apache.uima.UimaContext;
+import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
+import org.apache.uima.fit.component.JCasAnnotator_ImplBase;
+import org.apache.uima.jcas.JCas;
+import org.apache.uima.resource.ResourceInitializationException;
+import org.hl7.fhir.dstu3.model.Bundle;
+
+/**
+ * Prototype writer for fhir json.
+ *
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 12/20/2017
+ */
+@PipeBitInfo(
+      name = "FhirJsonWriter",
+      description = "For ctakes_401.", role = PipeBitInfo.Role.WRITER
+)
+final public class FhirJsonWriter extends JCasAnnotator_ImplBase {
+
+   static private final Logger LOGGER = Logger.getLogger( "FhirJsonWriter" );
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public void initialize( final UimaContext context ) throws ResourceInitializationException {
+      // Always call the super first
+      super.initialize( context );
+
+      // place AE initialization code here
+
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public void process( final JCas jCas ) throws AnalysisEngineProcessException {
+      LOGGER.info( "Processing ..." );
+
+      final Bundle bundle = FhirDocComposer.composeDocFhir( jCas, PractitionerCtakes.getInstance() );
+
+      final FhirContext fhirContext = FhirContext.forDstu3();
+      final IParser jsonParser = fhirContext.newJsonParser();
+      jsonParser.setPrettyPrint( true );
+      final String json = jsonParser.encodeResourceToString( bundle );
+      System.out.println( json );
+      System.out.println();
+      System.out.println();
+
+      LOGGER.info( "Finished." );
+   }
+
+
+}

Added: ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/cr/FhirXmlFileReader.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/cr/FhirXmlFileReader.java?rev=1825907&view=auto
==============================================================================
--- ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/cr/FhirXmlFileReader.java (added)
+++ ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/cr/FhirXmlFileReader.java Mon Mar  5 15:09:58 2018
@@ -0,0 +1,176 @@
+package org.apache.ctakes.fhir.cr;
+
+import ca.uhn.fhir.context.ConfigurationException;
+import ca.uhn.fhir.context.FhirContext;
+import ca.uhn.fhir.parser.DataFormatException;
+import ca.uhn.fhir.parser.IParser;
+import org.apache.ctakes.core.cr.AbstractFileTreeReader;
+import org.apache.ctakes.core.pipeline.PipeBitInfo;
+import org.apache.ctakes.core.util.RelationArgumentUtil;
+import org.apache.ctakes.fhir.element.FhirElementParser;
+import org.apache.ctakes.fhir.resource.AnnotationBasicParser;
+import org.apache.ctakes.fhir.resource.IdentifiedAnnotationBasicParser;
+import org.apache.ctakes.fhir.resource.SectionBasicParser;
+import org.apache.ctakes.typesystem.type.relation.BinaryTextRelation;
+import org.apache.ctakes.typesystem.type.textsem.IdentifiedAnnotation;
+import org.apache.log4j.Logger;
+import org.apache.uima.jcas.JCas;
+import org.apache.uima.jcas.tcas.Annotation;
+import org.hl7.fhir.dstu3.model.*;
+import org.hl7.fhir.instance.model.api.IBaseResource;
+import org.hl7.fhir.utilities.xhtml.XhtmlNode;
+
+import java.io.*;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.apache.ctakes.fhir.element.FhirElementFactory.CTAKES_FHIR_URL;
+import static org.apache.ctakes.fhir.element.FhirElementFactory.RELATION_EXT_PREFIX;
+import static org.apache.ctakes.fhir.resource.AnnotationBasicCreator.ID_NAME_ANNOTATION;
+import static org.apache.ctakes.fhir.resource.IdentifiedAnnotationBasicCreator.ID_NAME_IDENTIFIED_ANNOTATION;
+import static org.apache.ctakes.fhir.resource.SectionBasicCreator.ID_NAME_SECTION;
+import static org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent;
+
+
+/**
+ * Unfinished collection reader to create ctakes annotations from fhir files.
+ *
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 1/22/2018
+ */
+@PipeBitInfo(
+      name = "FhirXmlFileReader",
+      description = "Reads fhir information from xml.", role = PipeBitInfo.Role.READER
+)
+public class FhirXmlFileReader extends AbstractFileTreeReader {
+
+   static private final Logger LOGGER = Logger.getLogger( "FhirXmlFileReader" );
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected void readFile( final JCas jCas, final File file ) throws IOException {
+      jCas.reset();
+
+      final Bundle bundle = readBundle( file );
+
+      final SectionBasicParser sectionParser = new SectionBasicParser();
+      final AnnotationBasicParser annotationParser = new AnnotationBasicParser();
+      final IdentifiedAnnotationBasicParser iaParser = new IdentifiedAnnotationBasicParser();
+      // Build map of resources to annotations, sections, etc.
+      final List<BundleEntryComponent> entries = bundle.getEntry();
+      final Map<IBaseResource, Annotation> resourceAnnotations = new HashMap<>( entries.size() );
+      for ( BundleEntryComponent entry : entries ) {
+         final IBaseResource resource = entry.getResource();
+         final Annotation annotation = parseResource( jCas, resource, sectionParser, annotationParser, iaParser );
+         if ( annotation != null ) {
+            resourceAnnotations.put( resource, annotation );
+         }
+      }
+
+      // Go through the (Basic) entries in the map and build relations
+      for ( Map.Entry<IBaseResource, Annotation> resourceAnnotation : resourceAnnotations.entrySet() ) {
+         if ( !Basic.class.isInstance( resourceAnnotation.getKey() ) ) {
+            continue;
+         }
+         final Basic basic = (Basic) resourceAnnotation.getKey();
+         final List<Extension> extensions = basic.getExtension();
+         for ( Extension extension : extensions ) {
+            final String url = extension.getUrl();
+            if ( url.startsWith( CTAKES_FHIR_URL + RELATION_EXT_PREFIX ) ) {
+               final Type type = extension.getValue();
+               if ( type instanceof Reference ) {
+                  final IBaseResource resource = ((Reference) type).getResource();
+                  final Annotation target = resourceAnnotations.get( resource );
+                  if ( target != null ) {
+                     createRelation( jCas, url, resourceAnnotation.getValue(), target );
+                  }
+               }
+            }
+         }
+      }
+
+      // TODO build Map<Integer,Collection<Annotation>> with coref chain index to annotations that belong from the Basic Extensions
+   }
+
+
+   static private void createRelation( final JCas jCas, final String url,
+                                       final Annotation source, final Annotation target ) {
+      if ( source instanceof IdentifiedAnnotation && target instanceof IdentifiedAnnotation ) {
+         final String category = url.substring( (CTAKES_FHIR_URL + RELATION_EXT_PREFIX).length() );
+         final BinaryTextRelation relation
+               = RelationArgumentUtil.createRelation( jCas, (IdentifiedAnnotation) source, (IdentifiedAnnotation) target,
+               category );
+         relation.addToIndexes();
+      }
+   }
+
+
+   // TODO
+   static private void createCoreference( final JCas jCas, Collection<Annotation> marked ) {
+
+   }
+
+
+   static private Annotation parseResource( final JCas jCas,
+                                            final IBaseResource resource,
+                                            final SectionBasicParser sectionParser,
+                                            final AnnotationBasicParser annotationParser,
+                                            final IdentifiedAnnotationBasicParser iaParser ) {
+      if ( resource instanceof Composition ) {
+         final Narrative narrative = ((Composition) resource).getText();
+         final XhtmlNode html = narrative.getDiv();
+         final String docText = html.allText();
+         jCas.setDocumentText( docText );
+         return null;
+      }
+      Annotation annotation = null;
+      if ( resource instanceof Basic ) {
+         final Basic basic = (Basic) resource;
+         final String idName = FhirElementParser.getIdName( basic.getId() );
+         switch ( idName ) {
+            case ID_NAME_SECTION:
+               annotation = sectionParser.parseResource( jCas, basic );
+               break;
+            case ID_NAME_ANNOTATION:
+               annotation = annotationParser.parseResource( jCas, basic );
+               break;
+            case ID_NAME_IDENTIFIED_ANNOTATION:
+               annotation = iaParser.parseResource( jCas, basic );
+               break;
+         }
+         if ( annotation != null ) {
+            annotation.addToIndexes();
+            return annotation;
+         }
+      }
+      return null;
+   }
+
+
+   static private Bundle readBundle( final File file ) throws IOException {
+      IBaseResource baseResource;
+      final FhirContext fhirContext = FhirContext.forDstu3();
+      final IParser xmlParser = fhirContext.newXmlParser();
+      try ( Reader reader = new BufferedReader( new FileReader( file ) ) ) {
+         baseResource = xmlParser.parseResource( reader );
+
+      } catch ( IOException | ConfigurationException | DataFormatException multE ) {
+         LOGGER.error( "Could not read fhir from " + file.getAbsolutePath(), multE );
+         throw new IOException( multE );
+      }
+      if ( baseResource == null ) {
+         throw new IOException( "Null Bundle for file " + file.getAbsolutePath() );
+      }
+      if ( !Bundle.class.isInstance( baseResource ) ) {
+         throw new IOException( "Resource is not a Bundle for file " + file.getAbsolutePath() );
+      }
+      return (Bundle) baseResource;
+   }
+
+
+}

Added: ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/element/FhirElementFactory.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/element/FhirElementFactory.java?rev=1825907&view=auto
==============================================================================
--- ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/element/FhirElementFactory.java (added)
+++ ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/element/FhirElementFactory.java Mon Mar  5 15:09:58 2018
@@ -0,0 +1,288 @@
+package org.apache.ctakes.fhir.element;
+
+
+import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
+import org.apache.ctakes.core.semantic.SemanticGroup;
+import org.apache.ctakes.core.util.DocumentIDAnnotationUtil;
+import org.apache.ctakes.core.util.OntologyConceptUtil;
+import org.apache.ctakes.typesystem.type.refsem.Event;
+import org.apache.ctakes.typesystem.type.refsem.EventProperties;
+import org.apache.ctakes.typesystem.type.refsem.OntologyConcept;
+import org.apache.ctakes.typesystem.type.refsem.UmlsConcept;
+import org.apache.ctakes.typesystem.type.textsem.EventMention;
+import org.apache.ctakes.typesystem.type.textsem.IdentifiedAnnotation;
+import org.apache.log4j.Logger;
+import org.apache.uima.jcas.JCas;
+import org.hl7.fhir.dstu3.model.*;
+import org.hl7.fhir.utilities.xhtml.NodeType;
+import org.hl7.fhir.utilities.xhtml.XhtmlNode;
+
+import java.util.Collection;
+import java.util.Date;
+
+import static org.apache.ctakes.fhir.resource.SectionBasicCreator.SECTION_EXT;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 12/22/2017
+ */
+final public class FhirElementFactory {
+
+   static private final Logger LOGGER = Logger.getLogger( "FhirElementFactory" );
+
+   static public final String CTAKES_FHIR_URL = "http://org.apache.ctakes/fhir/";
+   static public final String SPAN_BEGIN_EXT = "span-begin";
+   static public final String SPAN_END_EXT = "span-end";
+   static public final String DOCTIMEREL_EXT = "doc-time-rel";
+   static public final String RELATION_EXT_PREFIX = "relation-";
+   static public final String COREF_INDEX_EXT = "coreference-index";
+
+   static public final String CODING_TYPE_SYSTEM = "type-system";
+   static public final String CODING_CUI = "cui";
+   static public final String CODING_TUI = "tui";
+   static public final String CODING_SEMANTIC = "semantic-group";
+
+
+   private FhirElementFactory() {
+   }
+
+   /**
+    * @param url       full url.
+    * @param extension url extension.
+    * @return true if the url is "http://org.apache.ctakes/fhir/" + extension.
+    */
+   static public boolean isCtakesFhirExt( final String url, final String extension ) {
+      return url.equals( CTAKES_FHIR_URL + extension );
+   }
+
+   /**
+    * @param extension url extension.
+    * @return "http://org.apache.ctakes/fhir/" + extension.
+    */
+   static public String createCtakesFhirUrl( final String extension ) {
+      return CTAKES_FHIR_URL + extension;
+   }
+
+   /**
+    * @param annotation -
+    * @return annotation type, all ontology codes and covered text in a fhir codeable concept.
+    */
+   static public CodeableConcept createPrimaryCode( final IdentifiedAnnotation annotation ) {
+      final CodeableConcept codeableConcept = createSimpleCode( annotation );
+      codeableConcept.addCoding( new Coding( CODING_SEMANTIC, SemanticGroup.getBestGroup( annotation )
+            .getName(), "" ) );
+      final Collection<String> cuis = OntologyConceptUtil.getCuis( annotation );
+      cuis.forEach( c -> codeableConcept.addCoding( new Coding( CODING_CUI, c, "" ) ) );
+      final Collection<String> tuis = OntologyConceptUtil.getTuis( annotation );
+      tuis.forEach( t -> codeableConcept.addCoding( new Coding( CODING_TUI, t, "" ) ) );
+      for ( OntologyConcept concept : OntologyConceptUtil.getOntologyConcepts( annotation ) ) {
+         final String scheme = concept.getCodingScheme();
+         final String code = concept.getCode();
+         String preferredText = null;
+         if ( concept instanceof UmlsConcept ) {
+            preferredText = ((UmlsConcept) concept).getPreferredText();
+         }
+         codeableConcept.addCoding( new Coding( scheme, code, preferredText ) );
+      }
+      return codeableConcept;
+   }
+
+   /**
+    * @param annotation -
+    * @return annotation type and covered text in a fhir codeable concept.
+    */
+   static public CodeableConcept createSimpleCode( final org.apache.uima.jcas.tcas.Annotation annotation ) {
+      final String type = annotation.getType()
+            .getShortName();
+      return createSimpleCode( CODING_TYPE_SYSTEM, type, null, annotation.getCoveredText() );
+   }
+
+   /**
+    * @param system  -
+    * @param code    -
+    * @param display -
+    * @param text    -
+    * @return type, ontology code and covered text in a fhir codeable concept.
+    */
+   static public CodeableConcept createSimpleCode( final String system, final String code, final String display, final String text ) {
+      final CodeableConcept codeableConcept = new CodeableConcept();
+      codeableConcept.addCoding( new Coding( system, code, display ) );
+      codeableConcept.setText( text );
+      return codeableConcept;
+   }
+
+   /**
+    * @param codeableConcept -
+    * @param system          -
+    * @param code            -
+    * @param display         -
+    * @return the given fhir codeable concept with the given code added as a fhir Coding.
+    */
+   static public CodeableConcept addCoding( final CodeableConcept codeableConcept, final String system, final String code, final String display ) {
+      codeableConcept.addCoding( new Coding( system, code, display ) );
+      return codeableConcept;
+   }
+
+   /**
+    * @param jCas ye olde ...
+    * @param name fhir object type / name.
+    * @param code some numerical encoding to use in a fhir id.
+    * @return fhir id containing name and code.
+    */
+   static public String createId( final JCas jCas, final String name, final int code ) {
+      return createId( jCas, name, "" + Math.abs( code ) );
+   }
+
+   /**
+    * @param jCas ye olde ...
+    * @param name fhir object type / name.
+    * @param code some text encoding to use in a fhir id.
+    * @return fhir id containing name and code.
+    */
+   static public String createId( final JCas jCas, final String name, final String code ) {
+      return DocumentIDAnnotationUtil.getDocumentID( jCas ) + "_" + name + "_" + code;
+   }
+
+//   Identifiers are 0 .. 1 , so unnecessary
+//   static public Identifier createIdentifier( final JCas jCas,
+//                                              final org.apache.uima.jcas.tcas.Annotation annotation,
+//                                              final Period period ) {
+//      return createIdentifier( jCas, annotation.getType().getShortName(), annotation.hashCode(), period );
+//   }
+//
+//   static public Identifier createIdentifier( final JCas jCas,
+//                                              final String name,
+//                                              final Period period ) {
+//      return createIdentifier( jCas, name, name.hashCode(), period );
+//   }
+//
+//   static public Identifier createIdentifier( final JCas jCas,
+//                                              final String name,
+//                                              final int code,
+//                                              final Period period ) {
+//      return createIdentifier( jCas, name, ""+Math.abs( code ), period );
+//   }
+//
+//   static public Identifier createIdentifier( final JCas jCas,
+//                                              final String name,
+//                                              final String code,
+//                                              final Period period ) {
+//      final String id = DocumentIDAnnotationUtil.getDocumentID( jCas )
+//            + "_" + name
+//            + "_" + code;
+//      final Identifier identifier = new Identifier();
+//      identifier.setSystem( CTAKES_FHIR_URL + IDENTIFIER_EXT );
+//      identifier.setUse( Identifier.IdentifierUse.SECONDARY );
+//      identifier.setValue( id );
+//      identifier.setPeriod( period );
+//      return identifier;
+//   }
+
+   /**
+    * @param number some integer
+    * @return given integer wrapped in a fhir SimpleQuantity object
+    */
+   static public SimpleQuantity createQuantity( final int number ) {
+      final SimpleQuantity quantity = new SimpleQuantity();
+      quantity.setValue( number );
+      return quantity;
+   }
+
+   /**
+    * @param startMillis -
+    * @param endMillis   -
+    * @return fhir period spanning the given milliseconds.
+    */
+   static public Period createPeriod( final long startMillis, final long endMillis ) {
+      final Period period = new Period();
+      period.setStart( new Date( startMillis ), TemporalPrecisionEnum.MILLI );
+      period.setEnd( new Date( endMillis ), TemporalPrecisionEnum.MILLI );
+      return period;
+   }
+
+   /**
+    * @param text -
+    * @return fhir narrative object containing the given text wrapped in an html "div".
+    */
+   static public Narrative createNarrative( final String text ) {
+      final Narrative narrative = new Narrative();
+      narrative.setStatus( Narrative.NarrativeStatus.GENERATED );
+      final XhtmlNode htmlNode = new XhtmlNode( NodeType.Element, "div" );
+      htmlNode.addText( text );
+      narrative.setDiv( htmlNode );
+      return narrative;
+   }
+
+   /**
+    * @param annotation ctakes annotation.
+    * @return a fhir extension representing the annotation's beginning text span offset.
+    */
+   static public Extension createSpanBegin( final org.apache.uima.jcas.tcas.Annotation annotation ) {
+      final UnsignedIntType begin = new UnsignedIntType( annotation.getBegin() );
+      return new Extension( createCtakesFhirUrl( SPAN_BEGIN_EXT ), begin );
+   }
+
+   /**
+    * @param annotation ctakes annotation.
+    * @return a fhir extension representing the annotation's ending text span offset.
+    */
+   static public Extension createSpanEnd( final org.apache.uima.jcas.tcas.Annotation annotation ) {
+      final UnsignedIntType end = new UnsignedIntType( annotation.getEnd() );
+      return new Extension( createCtakesFhirUrl( SPAN_END_EXT ), end );
+   }
+
+   /**
+    * @param eventMention ctakes event.
+    * @return a fhir extension representing the time relative to document creation.
+    */
+   static public Extension createDocTimeRel( final EventMention eventMention ) {
+      final Event event = eventMention.getEvent();
+      if ( event == null ) {
+         return null;
+      }
+      final EventProperties eventProperties = event.getProperties();
+      if ( eventProperties == null ) {
+         return null;
+      }
+      final String dtr = eventProperties.getDocTimeRel();
+      if ( dtr == null || dtr.isEmpty() ) {
+         return null;
+      }
+      return new Extension( createCtakesFhirUrl( DOCTIMEREL_EXT ), new StringType( dtr ) );
+   }
+
+   /**
+    * @param name   relation name.
+    * @param target fhir object for the relation target.
+    * @return a fhir extension with the relation name and fhir reference to the target.
+    */
+   static public Extension createRelation( final String name, final Basic target ) {
+      return new Extension( createCtakesFhirUrl( RELATION_EXT_PREFIX + name ), new Reference( target ) );
+   }
+
+   /**
+    * @param index coreference chain index.
+    * @return a fhir extension indicating the coreference chain to which an object belongs.
+    */
+   static public Extension createCorefIndex( final int index ) {
+      return new Extension( createCtakesFhirUrl( COREF_INDEX_EXT ), new UnsignedIntType( index ) );
+   }
+
+   /**
+    * @param sectionRef reference to fhir object with section.
+    * @return a fhir extension indicating to which section an object belongs.
+    */
+   static public Extension createSectionExtension( final Reference sectionRef ) {
+      return new Extension( createCtakesFhirUrl( SECTION_EXT ), sectionRef );
+   }
+
+   /**
+    * @param name some property name.
+    * @return an extension indicating that an object property is true.
+    */
+   static public Extension createTrueExtension( final String name ) {
+      return new Extension( createCtakesFhirUrl( name ), new BooleanType( true ) );
+   }
+
+}

Added: ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/element/FhirElementParser.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/element/FhirElementParser.java?rev=1825907&view=auto
==============================================================================
--- ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/element/FhirElementParser.java (added)
+++ ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/element/FhirElementParser.java Mon Mar  5 15:09:58 2018
@@ -0,0 +1,184 @@
+package org.apache.ctakes.fhir.element;
+
+
+import org.apache.ctakes.core.util.Pair;
+import org.apache.ctakes.core.util.StringUtil;
+import org.apache.ctakes.typesystem.type.refsem.UmlsConcept;
+import org.apache.log4j.Logger;
+import org.apache.uima.jcas.JCas;
+import org.hl7.fhir.dstu3.model.*;
+import org.hl7.fhir.instance.model.api.IBaseExtension;
+import org.hl7.fhir.instance.model.api.IPrimitiveType;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.apache.ctakes.fhir.element.FhirElementFactory.*;
+
+/**
+ * Utility to assist with the creation of ctakes objects from fhir objects.
+ *
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 1/22/2018
+ */
+final public class FhirElementParser {
+
+   static private final Logger LOGGER = Logger.getLogger( "FhirElementParser" );
+
+   private FhirElementParser() {
+   }
+
+   static public String getIdName( final String id ) {
+      final String[] splits = StringUtil.fastSplit( id, '_' );
+      if ( splits.length >= 3 ) {
+         return splits[ 1 ];
+      }
+      return id;
+   }
+
+   // TODO handle subjects
+   static public String getSubjectId( final Basic basic ) {
+      final Reference reference = basic.getSubject();
+      if ( reference == null ) {
+         return "";
+      }
+      return reference.getResource()
+            .getIdElement()
+            .getValue();
+   }
+
+   static public Pair<Integer> getTextSpan( final Collection<Extension> extensions ) {
+      int begin = Integer.MAX_VALUE;
+      int end = Integer.MIN_VALUE;
+      for ( Extension extension : extensions ) {
+         final String url = extension.getUrl();
+         if ( isCtakesFhirExt( url, SPAN_BEGIN_EXT ) ) {
+            begin = parseInteger( extension );
+            if ( end != Integer.MIN_VALUE ) {
+               break;
+            }
+         } else if ( isCtakesFhirExt( url, SPAN_END_EXT ) ) {
+            end = parseInteger( extension );
+            if ( begin != Integer.MAX_VALUE ) {
+               break;
+            }
+         }
+      }
+      if ( end < begin ) {
+         LOGGER.error( "Could not parse text span." );
+         return null;
+      }
+      return new Pair<>( begin, end );
+   }
+
+   static public int getTextSpanBegin( final DomainResource resource ) {
+      final String url = createCtakesFhirUrl( SPAN_BEGIN_EXT );
+      return resource.getExtensionsByUrl( url )
+            .stream()
+            .mapToInt( FhirElementParser::parseInteger )
+            .min()
+            .orElse( Integer.MAX_VALUE );
+   }
+
+   static public int getTextSpanEnd( final DomainResource resource ) {
+      final String url = createCtakesFhirUrl( SPAN_END_EXT );
+      return resource.getExtensionsByUrl( url )
+            .stream()
+            .mapToInt( FhirElementParser::parseInteger )
+            .max()
+            .orElse( Integer.MIN_VALUE );
+   }
+
+   static public Collection<UmlsConcept> getUmlsConceptArray( final JCas jCas,
+                                                              final CodeableConcept codeableConcept ) {
+      final List<Coding> codings = codeableConcept.getCoding();
+      String cui = "";
+      String tui = "";
+      final Collection<UmlsConcept> umlsConcepts = new ArrayList<>();
+      for ( Coding coding : codings ) {
+         final String codeType = coding.getSystem();
+         switch ( codeType ) {
+            case CODING_CUI:
+               cui = coding.getCode();
+               continue;
+            case CODING_TUI:
+               tui = coding.getCode();
+         }
+      }
+      for ( Coding coding : codings ) {
+         final String codingSystem = coding.getSystem();
+         if ( codingSystem.equals( CODING_CUI )
+               || codingSystem.equals( CODING_TUI )
+               || codingSystem.equals( CODING_TYPE_SYSTEM )
+               || codingSystem.equals( CODING_SEMANTIC ) ) {
+            continue;
+         }
+         final String code = coding.getCode();
+         final String preferredText = coding.getDisplay();
+         final UmlsConcept umlsConcept = new UmlsConcept( jCas );
+         umlsConcept.setCodingScheme( codingSystem );
+         umlsConcept.setCui( cui );
+         if ( !tui.isEmpty() ) {
+            umlsConcept.setTui( tui );
+         }
+         umlsConcept.setCode( code );
+         if ( preferredText != null && !preferredText.isEmpty() ) {
+            umlsConcept.setPreferredText( preferredText );
+         }
+         umlsConcepts.add( umlsConcept );
+      }
+      return umlsConcepts;
+   }
+
+   static public String getCode( final CodeableConcept codeableConcept, final String schema ) {
+      return codeableConcept.getCoding()
+            .stream()
+            .filter( c -> c.getSystem()
+                  .equals( schema ) )
+            .findFirst()
+            .map( Coding::getCode )
+            .orElse( "" );
+   }
+
+   static public List<String> getExtensionValues( final String url, final List<? extends IBaseExtension> extensions ) {
+      return extensions.stream()
+            .filter( e -> e.getUrl()
+                  .equals( url ) )
+            .map( IBaseExtension::getValue )
+            .filter( StringType.class::isInstance )
+            .map( e -> ((StringType) e).getValue() )
+            .collect( Collectors.toList() );
+   }
+
+   static public boolean hasExtension( final String extension, final List<Extension> extensions ) {
+      final String url = createCtakesFhirUrl( extension );
+      return extensions.stream()
+            .anyMatch( e -> e.getUrl()
+                  .equals( url ) );
+   }
+
+   static public String parseString( final Extension extension ) {
+      IPrimitiveType primitiveType = extension.getValueAsPrimitive();
+      final Object value = primitiveType.getValue();
+      if ( value instanceof String ) {
+         return (String) value;
+      }
+      LOGGER.error( "Could not parse String for " + extension.getUrl() + " from " + value );
+      return value.toString();
+   }
+
+   static public int parseInteger( final Extension extension ) {
+      IPrimitiveType primitiveType = extension.getValueAsPrimitive();
+      final Object value = primitiveType.getValue();
+      if ( value instanceof Integer ) {
+         return (int) value;
+      }
+      LOGGER.error( "Could not parse integer for " + extension.getUrl() + " from " + value );
+      return -1;
+   }
+
+
+}

Modified: ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/AnnotationBasicCreator.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/AnnotationBasicCreator.java?rev=1825907&r1=1825906&r2=1825907&view=diff
==============================================================================
--- ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/AnnotationBasicCreator.java (original)
+++ ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/AnnotationBasicCreator.java Mon Mar  5 15:09:58 2018
@@ -1,42 +1,45 @@
-package org.apache.ctakes.fhir.resource;
-
-
-import org.apache.ctakes.fhir.cc.FhirElementFactory;
-import org.apache.ctakes.fhir.util.NoteSpecs;
-import org.apache.log4j.Logger;
-import org.apache.uima.jcas.JCas;
-import org.apache.uima.jcas.tcas.Annotation;
-import org.hl7.fhir.dstu3.model.Basic;
-
-import java.util.Date;
-
-/**
- * @author SPF , chip-nlp
- * @version %I%
- * @since 12/25/2017
- */
-final public class AnnotationBasicCreator implements FhirResourceCreator<Annotation, Basic> {
-
-   static private final Logger LOGGER = Logger.getLogger( "AnnotationBasicCreator" );
-
-   /**
-    * {@inheritDoc}
-    */
-   @Override
-   public Basic createResource( final JCas jCas, final Annotation annotation, final NoteSpecs noteSpecs ) {
-      final Basic basic = new Basic();
-      // The 'id' is name of the Resource type (class).  e.g. DiseaseDisorderMention
-      basic.setId( FhirElementFactory.createId( jCas, annotation ) );
-      // The 'code' is the full ontology concept array: cuis, snomeds, urls, preferred text, PLUS covered text.
-      basic.setCode( FhirElementFactory.createSimpleCode( annotation ) );
-      // Add Creation Date as now.
-      basic.setCreated( new Date() );
-      // Add Author (ctakes).
-      basic.setAuthor( PractitionerCtakes.getPractitionerReference() );
-      // Add text span as an extension.
-      basic.addExtension( FhirElementFactory.createSpanBegin( annotation ) );
-      basic.addExtension( FhirElementFactory.createSpanEnd( annotation ) );
-      return basic;
-   }
-
-}
+package org.apache.ctakes.fhir.resource;
+
+
+import org.apache.ctakes.fhir.element.FhirElementFactory;
+import org.apache.ctakes.fhir.util.FhirNoteSpecs;
+import org.apache.log4j.Logger;
+import org.apache.uima.jcas.JCas;
+import org.apache.uima.jcas.tcas.Annotation;
+import org.hl7.fhir.dstu3.model.Basic;
+
+import java.util.Date;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 12/25/2017
+ */
+final public class AnnotationBasicCreator implements FhirResourceCreator<Annotation, Basic> {
+
+   static private final Logger LOGGER = Logger.getLogger( "AnnotationBasicCreator" );
+
+   static public final String ID_NAME_ANNOTATION = "Annotation";
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public Basic createResource( final JCas jCas, final Annotation annotation, final FhirPractitioner practitioner,
+                                final FhirNoteSpecs noteSpecs ) {
+      final Basic basic = new Basic();
+      // The 'id' is name of the Resource type (class).  e.g. DiseaseDisorderMention
+      basic.setId( FhirElementFactory.createId( jCas, ID_NAME_ANNOTATION, annotation.hashCode() ) );
+      // The 'code' is the full ontology concept array: cuis, snomeds, urls, preferred text, PLUS covered text.
+      basic.setCode( FhirElementFactory.createSimpleCode( annotation ) );
+      // Add Creation Date as now.
+      basic.setCreated( new Date() );
+      // Add Author (ctakes).
+      basic.setAuthor( practitioner.getPractitionerReference() );
+      // Add text span as an extension.
+      basic.addExtension( FhirElementFactory.createSpanBegin( annotation ) );
+      basic.addExtension( FhirElementFactory.createSpanEnd( annotation ) );
+      return basic;
+   }
+
+}

Added: ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/AnnotationBasicParser.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/AnnotationBasicParser.java?rev=1825907&view=auto
==============================================================================
--- ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/AnnotationBasicParser.java (added)
+++ ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/AnnotationBasicParser.java Mon Mar  5 15:09:58 2018
@@ -0,0 +1,66 @@
+package org.apache.ctakes.fhir.resource;
+
+import org.apache.ctakes.core.util.Pair;
+import org.apache.ctakes.fhir.element.FhirElementParser;
+import org.apache.log4j.Logger;
+import org.apache.uima.jcas.JCas;
+import org.apache.uima.jcas.tcas.Annotation;
+import org.hl7.fhir.dstu3.model.Basic;
+import org.hl7.fhir.dstu3.model.CodeableConcept;
+import org.hl7.fhir.dstu3.model.Coding;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+import static org.apache.ctakes.fhir.element.FhirElementFactory.CODING_TYPE_SYSTEM;
+
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 1/22/2018
+ */
+final public class AnnotationBasicParser implements FhirResourceParser<Annotation, Basic> {
+
+   static private final Logger LOGGER = Logger.getLogger( "AnnotationBasicParser" );
+
+   public Annotation parseResource( final JCas jCas, final Basic resource ) {
+      String className = "";
+      final CodeableConcept codeableConcept = resource.getCode();
+      for ( Coding coding : codeableConcept.getCoding() ) {
+         final String system = coding.getSystem();
+         if ( system.equals( CODING_TYPE_SYSTEM ) ) {
+            className = coding.getCode();
+         }
+      }
+      final Annotation annotation = createAnnotation( jCas, className );
+      final Pair<Integer> textSpan = FhirElementParser.getTextSpan( resource.getExtension() );
+      if ( textSpan == null ) {
+         LOGGER.error( "Could not parse text span for annotation basic " + resource.getId() );
+         return null;
+      }
+      annotation.setBegin( textSpan.getValue1() );
+      annotation.setEnd( textSpan.getValue2() );
+      return annotation;
+   }
+
+
+   static private Annotation createAnnotation( final JCas jCas, final String className ) {
+      try {
+         final Class<?> clazz = Class.forName( className );
+         if ( Annotation.class.isAssignableFrom( clazz ) ) {
+            final Constructor<?> constructor = clazz.getConstructor( JCas.class );
+            return (Annotation) constructor.newInstance( jCas );
+         } else {
+            LOGGER.error( "Cannot create a ctakes annotation for class " + className );
+         }
+      } catch ( ClassNotFoundException | NoSuchMethodException
+            | InstantiationException
+            | IllegalAccessException
+            | InvocationTargetException multE ) {
+         LOGGER.error( "Cannot determine ctakes annotation type for class " + className );
+      }
+      return new Annotation( jCas );
+   }
+
+}

Modified: ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/BundleCreator.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/BundleCreator.java?rev=1825907&r1=1825906&r2=1825907&view=diff
==============================================================================
--- ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/BundleCreator.java (original)
+++ ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/BundleCreator.java Mon Mar  5 15:09:58 2018
@@ -1,40 +1,41 @@
-package org.apache.ctakes.fhir.resource;
-
-import org.apache.ctakes.fhir.cc.FhirElementFactory;
-import org.apache.ctakes.fhir.util.NoteSpecs;
-import org.apache.log4j.Logger;
-import org.apache.uima.jcas.JCas;
-import org.apache.uima.jcas.cas.TOP;
-import org.hl7.fhir.dstu3.model.Bundle;
-
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-
-/**
- * @author SPF , chip-nlp
- * @version %I%
- * @since 12/25/2017
- */
-final public class BundleCreator implements FhirResourceCreator<TOP, Bundle> {
-
-   static private final Logger LOGGER = Logger.getLogger( "BundleCreator" );
-
-   static private final String CTAKES_BUNDLE_ID = "ctakes_bundle";
-   static private final DateFormat DATE_FORMAT = new SimpleDateFormat( "yyyyMMddhhmm" );
-
-   /**
-    * {@inheritDoc}
-    */
-   @Override
-   public Bundle createResource( final JCas jCas, final TOP nullified, final NoteSpecs noteSpecs ) {
-      final Bundle bundle = new Bundle();
-      final String noteTime = DATE_FORMAT.format( new Date() );
-      bundle.setId( FhirElementFactory.createId( jCas, CTAKES_BUNDLE_ID, noteTime ) );
-      // The bundle is a collection; created for ease of distribution.
-      bundle.setType( Bundle.BundleType.COLLECTION );
-      return bundle;
-   }
-
-}
+package org.apache.ctakes.fhir.resource;
+
+import org.apache.ctakes.fhir.element.FhirElementFactory;
+import org.apache.ctakes.fhir.util.FhirNoteSpecs;
+import org.apache.log4j.Logger;
+import org.apache.uima.jcas.JCas;
+import org.apache.uima.jcas.cas.TOP;
+import org.hl7.fhir.dstu3.model.Bundle;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 12/25/2017
+ */
+final public class BundleCreator implements FhirResourceCreator<TOP, Bundle> {
+
+   static private final Logger LOGGER = Logger.getLogger( "BundleCreator" );
+
+   static private final String CTAKES_BUNDLE_ID = "ctakes_bundle";
+   static private final DateFormat DATE_FORMAT = new SimpleDateFormat( "yyyyMMddhhmm" );
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public Bundle createResource( final JCas jCas, final TOP nullified, final FhirPractitioner practitioner,
+                                 final FhirNoteSpecs noteSpecs ) {
+      final Bundle bundle = new Bundle();
+      final String noteTime = DATE_FORMAT.format( new Date() );
+      bundle.setId( FhirElementFactory.createId( jCas, CTAKES_BUNDLE_ID, noteTime ) );
+      // The bundle is a collection; created for ease of distribution.
+      bundle.setType( Bundle.BundleType.COLLECTION );
+      return bundle;
+   }
+
+}

Added: ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/CompositionCreator.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/CompositionCreator.java?rev=1825907&view=auto
==============================================================================
--- ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/CompositionCreator.java (added)
+++ ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/CompositionCreator.java Mon Mar  5 15:09:58 2018
@@ -0,0 +1,61 @@
+package org.apache.ctakes.fhir.resource;
+
+import org.apache.ctakes.fhir.element.FhirElementFactory;
+import org.apache.ctakes.fhir.util.FhirNoteSpecs;
+import org.apache.log4j.Logger;
+import org.apache.uima.jcas.JCas;
+import org.apache.uima.jcas.cas.TOP;
+import org.hl7.fhir.dstu3.model.CodeableConcept;
+import org.hl7.fhir.dstu3.model.Composition;
+
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 1/19/2018
+ */
+final public class CompositionCreator implements FhirResourceCreator<TOP, Composition> {
+
+   static private final Logger LOGGER = Logger.getLogger( "DpheCompositionCreator" );
+
+   static public final String ID_NAME_COMPOSITION = "Composition";
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public Composition createResource( final JCas jCas, final TOP nullified, final FhirPractitioner practitioner,
+                                      final FhirNoteSpecs noteSpecs ) {
+
+      final Composition composition = new Composition();
+
+      // 0 .. 1 , not necessary and mostly redundant with id
+//      composition.setIdentifier( FhirElementFactory.createIdentifier( jCas, DPHE_COMPOSITION_ID, noteSpecs.getPeriod() ) );
+
+      composition.addAuthor( practitioner.getPractitionerReference() );
+      composition.setId( FhirElementFactory.createId( jCas, ID_NAME_COMPOSITION, noteSpecs.getNoteTime() ) );
+      composition.setStatus( Composition.CompositionStatus.FINAL );
+      composition.setType( getCompositionType() );
+      composition.setLanguage( "English" );
+      composition.setSubject( noteSpecs.getSubjectReference( FhirNoteSpecs.SUBJECT_PATIENT ) );
+
+      // The following claim to have a 0 .. 1 cardinality, but the doc also states that they SHALL be listed.
+      composition.setEncounter( noteSpecs.getEncounterReference() );
+      composition.setCustodian( practitioner.getOrganizationReference() );
+//      composition.addEvent( noteSpecs.getEvent() );
+      composition.addAttester( practitioner.createAttester( noteSpecs ) );
+
+      composition.setText( FhirElementFactory.createNarrative( jCas.getDocumentText() ) );
+
+      return composition;
+   }
+
+   // TODO  CodeableConcept applicable to the note type
+   public CodeableConcept getCompositionType() {
+//            shortDefinition = "Kind of composition (LOINC if possible)",
+//            formalDefinition = "Specifies the particular kind of composition (e.g. History and Physical, Discharge Summary, Progress Note). This usually equates to the purpose of making the composition."
+      return new CodeableConcept();
+   }
+
+
+}

Added: ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/FhirPractitioner.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/FhirPractitioner.java?rev=1825907&view=auto
==============================================================================
--- ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/FhirPractitioner.java (added)
+++ ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/FhirPractitioner.java Mon Mar  5 15:09:58 2018
@@ -0,0 +1,103 @@
+package org.apache.ctakes.fhir.resource;
+
+import org.apache.ctakes.fhir.util.FhirNoteSpecs;
+import org.hl7.fhir.dstu3.model.*;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+import static org.hl7.fhir.dstu3.model.Composition.CompositionAttesterComponent;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 1/21/2018
+ */
+public interface FhirPractitioner {
+
+
+   String getName();
+
+   String getFamilyName();
+
+   String getVersion();
+
+   String getContactEmail();
+
+
+   /**
+    * @return Practitioner representation as the creator/extractor of data
+    */
+   Practitioner getPractitioner();
+
+   /**
+    * @return Reference to the Practitioner representation
+    */
+   Reference getPractitionerReference();
+
+   /**
+    * @return an organization for the practitioner
+    */
+   Organization getOrganization();
+
+   /**
+    * @return a reference to the organization for the practitioner
+    */
+   Reference getOrganizationReference();
+
+   /**
+    * @return Practitioner representation as the creator/extractor of data
+    */
+   default Practitioner createPractitioner() {
+      final HumanName name = new HumanName();
+      name.setUse( HumanName.NameUse.OFFICIAL );
+      name.setFamily( getFamilyName() );
+      name.addGiven( getName() );
+      final ContactPoint contact = new ContactPoint();
+      contact.setSystem( ContactPoint.ContactPointSystem.EMAIL );
+      contact.setValue( getContactEmail() );
+      contact.setUse( ContactPoint.ContactPointUse.WORK );
+      final Practitioner practitioner = new Practitioner();
+      String hostname;
+      try {
+         hostname = InetAddress.getLocalHost()
+               .getHostName();
+      } catch ( UnknownHostException uhE ) {
+         hostname = "UnknownHost";
+      }
+      practitioner.setId( getFamilyName() + '_' + getName() + '_' + getVersion() + "_" + hostname );
+      practitioner.setActive( true );
+      practitioner.addName( name );
+      practitioner.addTelecom( contact );
+      return practitioner;
+   }
+
+   /**
+    * @return an organization for the practitioner
+    */
+   default Organization createOrganization() {
+      final Organization organization = new Organization();
+      final Practitioner practitioner = getPractitioner();
+      final String id = practitioner.getId()
+            .replace( '_' + getName(), "" );
+      organization.setId( id );
+      organization.setActive( practitioner.getActive() );
+      organization.setName( getFamilyName() );
+      organization.setTelecom( practitioner.getTelecom() );
+      return organization;
+   }
+
+   /**
+    * @param noteSpecs information about a note
+    * @return an Attester for the given note with the Practitioner as the attesting party
+    */
+   default CompositionAttesterComponent createAttester( final FhirNoteSpecs noteSpecs ) {
+      final CompositionAttesterComponent attester = new CompositionAttesterComponent();
+      attester.addMode( Composition.CompositionAttestationMode.OFFICIAL );
+      attester.setTime( noteSpecs.getNoteDate() );
+      attester.setParty( getPractitionerReference() );
+      return attester;
+   }
+
+
+}

Modified: ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/FhirResourceCreator.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/FhirResourceCreator.java?rev=1825907&r1=1825906&r2=1825907&view=diff
==============================================================================
--- ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/FhirResourceCreator.java (original)
+++ ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/FhirResourceCreator.java Mon Mar  5 15:09:58 2018
@@ -1,17 +1,17 @@
-package org.apache.ctakes.fhir.resource;
-
-import org.apache.ctakes.fhir.util.NoteSpecs;
-import org.apache.uima.jcas.JCas;
-import org.apache.uima.jcas.cas.TOP;
-import org.hl7.fhir.dstu3.model.Resource;
-
-/**
- * @author SPF , chip-nlp
- * @version %I%
- * @since 12/25/2017
- */
-public interface FhirResourceCreator<T extends TOP, R extends Resource> {
-
-   R createResource( final JCas jCas, final T top, final NoteSpecs noteSpecs );
-
-}
+package org.apache.ctakes.fhir.resource;
+
+import org.apache.ctakes.fhir.util.FhirNoteSpecs;
+import org.apache.uima.jcas.JCas;
+import org.apache.uima.jcas.cas.TOP;
+import org.hl7.fhir.dstu3.model.Resource;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 12/25/2017
+ */
+public interface FhirResourceCreator<T extends TOP, R extends Resource> {
+
+   R createResource( final JCas jCas, final T top, final FhirPractitioner practitioner, final FhirNoteSpecs noteSpecs );
+
+}

Added: ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/FhirResourceParser.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/FhirResourceParser.java?rev=1825907&view=auto
==============================================================================
--- ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/FhirResourceParser.java (added)
+++ ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/FhirResourceParser.java Mon Mar  5 15:09:58 2018
@@ -0,0 +1,16 @@
+package org.apache.ctakes.fhir.resource;
+
+import org.apache.uima.jcas.JCas;
+import org.apache.uima.jcas.cas.TOP;
+import org.hl7.fhir.dstu3.model.Resource;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 1/22/2018
+ */
+public interface FhirResourceParser<T extends TOP, R extends Resource> {
+
+   T parseResource( final JCas jCas, final R resource );
+
+}

Modified: ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/IdentifiedAnnotationBasicCreator.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/IdentifiedAnnotationBasicCreator.java?rev=1825907&r1=1825906&r2=1825907&view=diff
==============================================================================
--- ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/IdentifiedAnnotationBasicCreator.java (original)
+++ ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/IdentifiedAnnotationBasicCreator.java Mon Mar  5 15:09:58 2018
@@ -1,73 +1,76 @@
-package org.apache.ctakes.fhir.resource;
-
-import org.apache.ctakes.fhir.cc.FhirElementFactory;
-import org.apache.ctakes.fhir.util.NoteSpecs;
-import org.apache.ctakes.typesystem.type.constants.CONST;
-import org.apache.ctakes.typesystem.type.textsem.EventMention;
-import org.apache.ctakes.typesystem.type.textsem.IdentifiedAnnotation;
-import org.apache.log4j.Logger;
-import org.apache.uima.jcas.JCas;
-import org.hl7.fhir.dstu3.model.Basic;
-import org.hl7.fhir.dstu3.model.Extension;
-
-import java.util.Date;
-
-
-/**
- * @author SPF , chip-nlp
- * @version %I%
- * @since 12/25/2017
- */
-final public class IdentifiedAnnotationBasicCreator implements FhirResourceCreator<IdentifiedAnnotation, Basic> {
-
-   static private final Logger LOGGER = Logger.getLogger( "IdentifiedAnnotationBasicCreator" );
-
-   static private final String GENERIC_EXT = "generic";
-   static private final String UNCERTAIN_EXT = "uncertain";
-   static private final String NEGATED_EXT = "negated";
-   static private final String HISTORIC_EXT = "historic";
-
-   /**
-    * {@inheritDoc}
-    */
-   @Override
-   public Basic createResource( final JCas jCas, final IdentifiedAnnotation annotation, final NoteSpecs noteSpecs ) {
-      final Basic basic = new Basic();
-      // The 'id' is name of the Resource type (class).  e.g. DiseaseDisorderMention
-      basic.setId( FhirElementFactory.createId( jCas, annotation ) );
-      // The 'code' is the full ontology concept array: cuis, snomeds, urls, preferred text, PLUS covered text.
-      basic.setCode( FhirElementFactory.createPrimaryCode( annotation ) );
-      // Add Subject reference.
-      basic.setSubject( noteSpecs.getSubjectReference( annotation.getSubject() ) );
-      // Add Creation Date as now.
-      basic.setCreated( new Date() );
-      // Add Author (ctakes).
-      basic.setAuthor( PractitionerCtakes.getPractitionerReference() );
-      // Add text span as an extension.
-      basic.addExtension( FhirElementFactory.createSpanBegin( annotation ) );
-      basic.addExtension( FhirElementFactory.createSpanEnd( annotation ) );
-      // Add DocTimeRel as an extension.
-      if ( annotation instanceof EventMention ) {
-         final Extension dtr = FhirElementFactory.createDocTimeRel( (EventMention) annotation );
-         if ( dtr != null ) {
-            basic.addExtension( dtr );
-         }
-      }
-      // Add generic, uncertainty, negation as modifier extensions.
-      if ( annotation.getGeneric() ) {
-         basic.addModifierExtension( FhirElementFactory.createTrueExtension( GENERIC_EXT ) );
-      }
-      if ( annotation.getUncertainty() == CONST.NE_UNCERTAINTY_PRESENT ) {
-         basic.addModifierExtension( FhirElementFactory.createTrueExtension( UNCERTAIN_EXT ) );
-      }
-      if ( annotation.getPolarity() == CONST.NE_POLARITY_NEGATION_PRESENT ) {
-         basic.addModifierExtension( FhirElementFactory.createTrueExtension( NEGATED_EXT ) );
-      }
-      // Add history of as a modifier extension.
-      if ( annotation.getHistoryOf() == CONST.NE_HISTORY_OF_PRESENT ) {
-         basic.addModifierExtension( FhirElementFactory.createTrueExtension( HISTORIC_EXT ) );
-      }
-      return basic;
-   }
-
-}
+package org.apache.ctakes.fhir.resource;
+
+import org.apache.ctakes.fhir.element.FhirElementFactory;
+import org.apache.ctakes.fhir.util.FhirNoteSpecs;
+import org.apache.ctakes.typesystem.type.constants.CONST;
+import org.apache.ctakes.typesystem.type.textsem.EventMention;
+import org.apache.ctakes.typesystem.type.textsem.IdentifiedAnnotation;
+import org.apache.log4j.Logger;
+import org.apache.uima.jcas.JCas;
+import org.hl7.fhir.dstu3.model.Basic;
+import org.hl7.fhir.dstu3.model.Extension;
+
+import java.util.Date;
+
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 12/25/2017
+ */
+final public class IdentifiedAnnotationBasicCreator implements FhirResourceCreator<IdentifiedAnnotation, Basic> {
+
+   static private final Logger LOGGER = Logger.getLogger( "IdentifiedAnnotationBasicCreator" );
+
+   static public final String ID_NAME_IDENTIFIED_ANNOTATION = "IdentifiedAnnotation";
+
+   static public final String GENERIC_EXT = "generic";
+   static public final String UNCERTAIN_EXT = "uncertain";
+   static public final String NEGATED_EXT = "negated";
+   static public final String HISTORIC_EXT = "historic";
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public Basic createResource( final JCas jCas, final IdentifiedAnnotation annotation,
+                                final FhirPractitioner practitioner, final FhirNoteSpecs noteSpecs ) {
+      final Basic basic = new Basic();
+      // The 'id' is name of the Resource type (class).  e.g. DiseaseDisorderMention
+      basic.setId( FhirElementFactory.createId( jCas, ID_NAME_IDENTIFIED_ANNOTATION, annotation.hashCode() ) );
+      // The 'code' is the full ontology concept array: cuis, snomeds, urls, preferred text, PLUS covered text.
+      basic.setCode( FhirElementFactory.createPrimaryCode( annotation ) );
+      // Add Subject reference.
+      basic.setSubject( noteSpecs.getSubjectReference( annotation.getSubject() ) );
+      // Add Creation Date as now.
+      basic.setCreated( new Date() );
+      // Add Author (ctakes).
+      basic.setAuthor( practitioner.getPractitionerReference() );
+      // Add text span as an extension.
+      basic.addExtension( FhirElementFactory.createSpanBegin( annotation ) );
+      basic.addExtension( FhirElementFactory.createSpanEnd( annotation ) );
+      // Add DocTimeRel as an extension.
+      if ( annotation instanceof EventMention ) {
+         final Extension dtr = FhirElementFactory.createDocTimeRel( (EventMention) annotation );
+         if ( dtr != null ) {
+            basic.addExtension( dtr );
+         }
+      }
+      // Add generic, uncertainty, negation as modifier extensions.
+      if ( annotation.getGeneric() ) {
+         basic.addModifierExtension( FhirElementFactory.createTrueExtension( GENERIC_EXT ) );
+      }
+      if ( annotation.getUncertainty() == CONST.NE_UNCERTAINTY_PRESENT ) {
+         basic.addModifierExtension( FhirElementFactory.createTrueExtension( UNCERTAIN_EXT ) );
+      }
+      if ( annotation.getPolarity() == CONST.NE_POLARITY_NEGATION_PRESENT ) {
+         basic.addModifierExtension( FhirElementFactory.createTrueExtension( NEGATED_EXT ) );
+      }
+      // Add history of as a modifier extension.
+      if ( annotation.getHistoryOf() == CONST.NE_HISTORY_OF_PRESENT ) {
+         basic.addModifierExtension( FhirElementFactory.createTrueExtension( HISTORIC_EXT ) );
+      }
+      return basic;
+   }
+
+}

Added: ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/IdentifiedAnnotationBasicParser.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/IdentifiedAnnotationBasicParser.java?rev=1825907&view=auto
==============================================================================
--- ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/IdentifiedAnnotationBasicParser.java (added)
+++ ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/IdentifiedAnnotationBasicParser.java Mon Mar  5 15:09:58 2018
@@ -0,0 +1,111 @@
+package org.apache.ctakes.fhir.resource;
+
+import org.apache.ctakes.core.semantic.SemanticGroup;
+import org.apache.ctakes.core.util.Pair;
+import org.apache.ctakes.fhir.element.FhirElementParser;
+import org.apache.ctakes.typesystem.type.constants.CONST;
+import org.apache.ctakes.typesystem.type.refsem.Event;
+import org.apache.ctakes.typesystem.type.refsem.EventProperties;
+import org.apache.ctakes.typesystem.type.refsem.UmlsConcept;
+import org.apache.ctakes.typesystem.type.textsem.EventMention;
+import org.apache.ctakes.typesystem.type.textsem.IdentifiedAnnotation;
+import org.apache.log4j.Logger;
+import org.apache.uima.jcas.JCas;
+import org.apache.uima.jcas.cas.FSArray;
+import org.hl7.fhir.dstu3.model.Basic;
+import org.hl7.fhir.dstu3.model.CodeableConcept;
+import org.hl7.fhir.dstu3.model.Coding;
+import org.hl7.fhir.dstu3.model.Extension;
+
+import java.util.Collection;
+import java.util.List;
+
+import static org.apache.ctakes.fhir.element.FhirElementFactory.*;
+import static org.apache.ctakes.fhir.resource.IdentifiedAnnotationBasicCreator.*;
+
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 1/22/2018
+ */
+final public class IdentifiedAnnotationBasicParser implements FhirResourceParser<IdentifiedAnnotation, Basic> {
+
+   static private final Logger LOGGER = Logger.getLogger( "IdentifiedAnnotationBasicParser" );
+
+   public IdentifiedAnnotation parseResource( final JCas jCas, final Basic resource ) {
+
+      final CodeableConcept codeableConcept = resource.getCode();
+      final List<Coding> codings = codeableConcept.getCoding();
+      // Get annotation semantic group id
+      final String groupName = FhirElementParser.getCode( codeableConcept, CODING_SEMANTIC );
+      final SemanticGroup group = SemanticGroup.getGroup( groupName );
+      // create annotation
+      final IdentifiedAnnotation annotation = createSemanticAnnotation( jCas, group );
+      annotation.setTypeID( group.getCode() );
+      // create OntologyConceptArray
+      final Collection<UmlsConcept> umlsConcepts = FhirElementParser.getUmlsConceptArray( jCas, codeableConcept );
+      final FSArray conceptArr = new FSArray( jCas, umlsConcepts.size() );
+      int arrIdx = 0;
+      for ( UmlsConcept umlsConcept : umlsConcepts ) {
+         conceptArr.set( arrIdx, umlsConcept );
+         arrIdx++;
+      }
+      annotation.setOntologyConceptArr( conceptArr );
+      // text span
+      final List<Extension> extensions = resource.getExtension();
+      final Pair<Integer> textSpan = FhirElementParser.getTextSpan( extensions );
+      if ( textSpan == null ) {
+         LOGGER.error( "Could not parse text span for annotation basic " + resource.getId() );
+         return null;
+      }
+      annotation.setBegin( textSpan.getValue1() );
+      annotation.setEnd( textSpan.getValue2() );
+
+      // Set properties
+      if ( FhirElementParser.hasExtension( GENERIC_EXT, extensions ) ) {
+         annotation.setGeneric( true );
+      }
+      if ( FhirElementParser.hasExtension( UNCERTAIN_EXT, extensions ) ) {
+         annotation.setUncertainty( CONST.NE_UNCERTAINTY_PRESENT );
+      }
+      if ( FhirElementParser.hasExtension( NEGATED_EXT, extensions ) ) {
+         annotation.setPolarity( CONST.NE_POLARITY_NEGATION_PRESENT );
+      }
+      if ( FhirElementParser.hasExtension( HISTORIC_EXT, extensions ) ) {
+         annotation.setHistoryOf( CONST.NE_HISTORY_OF_PRESENT );
+      }
+      // TODO subject
+      if ( annotation instanceof EventMention ) {
+         final Event event = createEvent( jCas, extensions );
+         if ( event != null ) {
+            ((EventMention) annotation).setEvent( event );
+         }
+      }
+
+      annotation.addToIndexes();
+      return annotation;
+   }
+
+   static private IdentifiedAnnotation createSemanticAnnotation( final JCas jcas, final SemanticGroup group ) {
+      return group.getCreator().apply( jcas );
+   }
+
+   static private Event createEvent( final JCas jCas, final Collection<Extension> extensions ) {
+      final String dtrUrl = createCtakesFhirUrl( DOCTIMEREL_EXT );
+      for ( Extension extension : extensions ) {
+         if ( !extension.getUrl()
+               .equals( dtrUrl ) ) {
+            continue;
+         }
+         final String dtr = FhirElementParser.parseString( extension );
+         final EventProperties properties = new EventProperties( jCas );
+         properties.setDocTimeRel( dtr );
+         final Event event = new Event( jCas );
+         event.setProperties( properties );
+         return event;
+      }
+      return null;
+   }
+
+}

Modified: ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/PractitionerCtakes.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/PractitionerCtakes.java?rev=1825907&r1=1825906&r2=1825907&view=diff
==============================================================================
--- ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/PractitionerCtakes.java (original)
+++ ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/PractitionerCtakes.java Mon Mar  5 15:09:58 2018
@@ -1,65 +1,88 @@
-package org.apache.ctakes.fhir.resource;
-
-
-import org.hl7.fhir.dstu3.model.ContactPoint;
-import org.hl7.fhir.dstu3.model.HumanName;
-import org.hl7.fhir.dstu3.model.Practitioner;
-import org.hl7.fhir.dstu3.model.Reference;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-
-/**
- * https://www.hl7.org/fhir/practitioner.html
- * Even though ctakes is not human, registering it as a Practitioner provides reference to information source and devlist contact
- *
- * @author SPF , chip-nlp
- * @version %I%
- * @since 12/25/2017
- */
-public enum PractitionerCtakes {
-   INSTANCE;
-
-   static private final String CTAKES_VERSION = "4_0_1";
-
-   /**
-    * @return Practitioner representing ctakes as the creator/extractor of data
-    */
-   static public Practitioner getPractitioner() {
-      return INSTANCE._ctakes;
-   }
-
-   /**
-    * @return Reference to a Practitioner representing ctakes as the creator/extractor of data
-    */
-   static public Reference getPractitionerReference() {
-      return INSTANCE._ctakesReference;
-   }
-
-   final private Practitioner _ctakes;
-   final private Reference _ctakesReference;
-
-   PractitionerCtakes() {
-      final HumanName name = new HumanName();
-      name.setUse( HumanName.NameUse.OFFICIAL );
-      name.setFamily( "Apache" );
-      name.addGiven( "cTAKES" );
-      final ContactPoint devlist = new ContactPoint();
-      devlist.setSystem( ContactPoint.ContactPointSystem.EMAIL );
-      devlist.setValue( "dev@ctakes.apache.org" );
-      devlist.setUse( ContactPoint.ContactPointUse.WORK );
-      _ctakes = new Practitioner();
-      String hostname = "UnknownHost";
-      try {
-         hostname = InetAddress.getLocalHost().getHostName();
-      } catch ( UnknownHostException uhE ) {
-         hostname = "UnknownHost";
-      }
-      _ctakes.setId( "Apache_cTAKES_" + CTAKES_VERSION + "_" + hostname );
-      _ctakes.setActive( true );
-      _ctakes.addName( name );
-      _ctakes.addTelecom( devlist );
-      _ctakesReference = new Reference( _ctakes );
-   }
-
-}
+package org.apache.ctakes.fhir.resource;
+
+
+import org.hl7.fhir.dstu3.model.Organization;
+import org.hl7.fhir.dstu3.model.Practitioner;
+import org.hl7.fhir.dstu3.model.Reference;
+
+/**
+ * https://www.hl7.org/fhir/practitioner.html
+ * Even though ctakes is not human, registering it as a Practitioner provides reference to information source and devlist contact
+ *
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 12/25/2017
+ */
+public enum PractitionerCtakes implements FhirPractitioner {
+   INSTANCE;
+
+   static public PractitionerCtakes getInstance() {
+      return INSTANCE;
+   }
+
+   @Override
+   public String getName() {
+      return "cTAKES";
+   }
+
+   @Override
+   public String getFamilyName() {
+      return "Apache";
+   }
+
+   @Override
+   public String getVersion() {
+      return "4_0_1";
+   }
+
+   @Override
+   public String getContactEmail() {
+      return "dev@ctakes.apache.org";
+   }
+
+   final private Practitioner _ctakes;
+   final private Reference _ctakesReference;
+
+   final private Organization _apache;
+   final private Reference _apacheReference;
+
+   PractitionerCtakes() {
+      _ctakes = createPractitioner();
+      _ctakesReference = new Reference( _ctakes );
+      _apache = createOrganization();
+      _apacheReference = new Reference( _apache );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public Practitioner getPractitioner() {
+      return _ctakes;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public Reference getPractitionerReference() {
+      return _ctakesReference;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public Organization getOrganization() {
+      return _apache;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public Reference getOrganizationReference() {
+      return _apacheReference;
+   }
+
+}

Modified: ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/SectionBasicCreator.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/SectionBasicCreator.java?rev=1825907&r1=1825906&r2=1825907&view=diff
==============================================================================
--- ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/SectionBasicCreator.java (original)
+++ ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/SectionBasicCreator.java Mon Mar  5 15:09:58 2018
@@ -1,52 +1,58 @@
-package org.apache.ctakes.fhir.resource;
-
-import org.apache.ctakes.fhir.cc.FhirElementFactory;
-import org.apache.ctakes.fhir.util.NoteSpecs;
-import org.apache.ctakes.typesystem.type.textspan.Segment;
-import org.apache.log4j.Logger;
-import org.apache.uima.jcas.JCas;
-import org.hl7.fhir.dstu3.model.Basic;
-import org.hl7.fhir.dstu3.model.CodeableConcept;
-import org.hl7.fhir.dstu3.model.Coding;
-
-import java.util.Date;
-
-
-/**
- * @author SPF , chip-nlp
- * @version %I%
- * @since 12/25/2017
- */
-final public class SectionBasicCreator implements FhirResourceCreator<Segment, Basic> {
-
-   static private final Logger LOGGER = Logger.getLogger( "SectionBasicCreator" );
-
-   static public final String SECTION_TYPE_NAME = "DocumentSection";
-
-   /**
-    * {@inheritDoc}
-    */
-   @Override
-   public Basic createResource( final JCas jCas, final Segment section, final NoteSpecs noteSpecs ) {
-      final Basic basic = new Basic();
-      // The 'id' is name of the Resource type (class).  e.g. DiseaseDisorderMention
-      basic.setId( FhirElementFactory.createId( jCas, SECTION_TYPE_NAME, section.hashCode() ) );
-      // The 'code' is the normalized section name PLUS section tag text.
-      final CodeableConcept codeableConcept = FhirElementFactory.createSimpleCode( section );
-      codeableConcept.addCoding( new Coding( "section-name", section.getPreferredText(), null ) );
-      if ( !section.getPreferredText().equals( section.getId() ) ) {
-         codeableConcept.addCoding( new Coding( "id", section.getId(), null ) );
-      }
-      codeableConcept.setText( section.getTagText() );
-      basic.setCode( codeableConcept );
-      // Add Creation Date as now.
-      basic.setCreated( new Date() );
-      // Add Author (ctakes).
-      basic.setAuthor( PractitionerCtakes.getPractitionerReference() );
-      // Add text span as an extension.
-      basic.addExtension( FhirElementFactory.createSpanBegin( section ) );
-      basic.addExtension( FhirElementFactory.createSpanEnd( section ) );
-      return basic;
-   }
-
-}
+package org.apache.ctakes.fhir.resource;
+
+import org.apache.ctakes.fhir.element.FhirElementFactory;
+import org.apache.ctakes.fhir.util.FhirNoteSpecs;
+import org.apache.ctakes.typesystem.type.textspan.Segment;
+import org.apache.log4j.Logger;
+import org.apache.uima.jcas.JCas;
+import org.hl7.fhir.dstu3.model.Basic;
+import org.hl7.fhir.dstu3.model.CodeableConcept;
+import org.hl7.fhir.dstu3.model.Coding;
+
+import java.util.Date;
+
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 12/25/2017
+ */
+final public class SectionBasicCreator implements FhirResourceCreator<Segment, Basic> {
+
+   static private final Logger LOGGER = Logger.getLogger( "SectionBasicCreator" );
+
+   static public final String CODING_SECTION_NAME = "section-name";
+   static public final String CODING_SECTION_ID = "section-id";
+
+   static public final String SECTION_EXT = "document-section";
+   static public final String ID_NAME_SECTION = "DocumentSection";
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public Basic createResource( final JCas jCas, final Segment section, final FhirPractitioner practitioner,
+                                final FhirNoteSpecs noteSpecs ) {
+      final Basic basic = new Basic();
+      // The 'id' is name of the Resource type (class).  e.g. DiseaseDisorderMention
+      basic.setId( FhirElementFactory.createId( jCas, ID_NAME_SECTION, section.hashCode() ) );
+      // The 'code' is the normalized section name PLUS section tag text.
+      final CodeableConcept codeableConcept = FhirElementFactory.createSimpleCode( section );
+      codeableConcept.addCoding( new Coding( CODING_SECTION_NAME, section.getPreferredText(), null ) );
+      if ( !section.getPreferredText()
+            .equals( section.getId() ) ) {
+         codeableConcept.addCoding( new Coding( CODING_SECTION_ID, section.getId(), null ) );
+      }
+      codeableConcept.setText( section.getTagText() );
+      basic.setCode( codeableConcept );
+      // Add Creation Date as now.
+      basic.setCreated( new Date() );
+      // Add Author (ctakes).
+      basic.setAuthor( practitioner.getPractitionerReference() );
+      // Add text span as an extension.
+      basic.addExtension( FhirElementFactory.createSpanBegin( section ) );
+      basic.addExtension( FhirElementFactory.createSpanEnd( section ) );
+      return basic;
+   }
+
+}