ctakes-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From seanfi...@apache.org
Subject svn commit: r1876808 - in /ctakes/trunk: ctakes-core/src/main/java/org/apache/ctakes/core/cr/ ctakes-core/src/main/java/org/apache/ctakes/core/util/ ctakes-examples/ ctakes-examples/src/main/java/org/apache/ctakes/examples/pipeline/ ctakes-fhir/src/mai...
Date Wed, 22 Apr 2020 02:34:29 GMT
Author: seanfinan
Date: Wed Apr 22 02:34:29 2020
New Revision: 1876808

URL: http://svn.apache.org/viewvc?rev=1876808&view=rev
Log:
JCasBuilder improvement with better build vs. rebuild method
AbstractFileTreeReader prep for refactor to JCasBuilder use
Add IdentifiedAnnotationUtil convenience utility
StringUtil fix for empty bsv columns
Add PiperCreatorGui to Examples
Add junit jupiter to Examples
Add runDictionaryGui profile to Examples
Add CtakesTypeCreator for suboptimal ctakes type to fhir resource mapping

Added:
    ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/util/IdentifiedAnnotationUtil.java
    ctakes/trunk/ctakes-examples/src/main/java/org/apache/ctakes/examples/pipeline/PiperCreatorGui.java
    ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/CtakesTypeCreator.java
Modified:
    ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cr/AbstractFileTreeReader.java
    ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cr/JCasBuilder.java
    ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/util/StringUtil.java
    ctakes/trunk/ctakes-examples/pom.xml

Modified: ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cr/AbstractFileTreeReader.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cr/AbstractFileTreeReader.java?rev=1876808&r1=1876807&r2=1876808&view=diff
==============================================================================
--- ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cr/AbstractFileTreeReader.java
(original)
+++ ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cr/AbstractFileTreeReader.java
Wed Apr 22 02:34:29 2020
@@ -175,6 +175,36 @@ abstract public class AbstractFileTreeRe
    }
 
    /**
+    * @return all files in the directory tree.
+    */
+   protected Collection<File> getFiles() {
+      return _files;
+   }
+
+   /**
+    * @return the index of the file currently being processed.
+    */
+   protected int getCurrentIndex() {
+      return _currentIndex;
+   }
+
+   /**
+    * Use with care.
+    *
+    * @param index of the file currently being processed.
+    */
+   protected void setCurrentIndex( final int index ) {
+      _currentIndex = index;
+   }
+
+   /**
+    * @return the patientId for that file.  By default this is the name of the directory
containing the file.
+    */
+   protected String getPatientId( final File file ) {
+      return _filePatients.get( file );
+   }
+
+   /**
     * Gets the total number of documents that will be returned by this
     * collection reader.
     *
@@ -440,6 +470,21 @@ abstract public class AbstractFileTreeRe
       return docText;
    }
 
+   protected JCasBuilder getJCasBuilder( final File file ) {
+      final String id = createDocumentID( file, getValidExtensions() );
+      final String idPrefix = createDocumentIdPrefix( file, getRootDir() );
+      final String docType = createDocumentType( id );
+      final String docTime = createDocumentTime( file );
+      final String patientId = _filePatients.get( file );
+      return new JCasBuilder()
+            .setDocId( id )
+            .setDocIdPrefix( idPrefix )
+            .setDocType( docType )
+            .setDocTime( docTime )
+            .setPatientId( patientId )
+            .setDocPath( file.getAbsolutePath() );
+   }
+
    /**
     * {@inheritDoc}
     */
@@ -464,6 +509,8 @@ abstract public class AbstractFileTreeRe
       LOGGER.info( "Reading " + id + " : " + file.getPath() );
       readFile( jcas, file );
       // Add document metadata based upon file path
+//      getJCasBuilder( file ).populate( jcas );  TODO replace the following with the builder.populate(
jcas );
+
       final DocumentID documentId = new DocumentID( jcas );
       documentId.setDocumentID( id );
       documentId.addToIndexes();
@@ -481,6 +528,7 @@ abstract public class AbstractFileTreeRe
       final DocumentPath documentPath = new DocumentPath( jcas );
       documentPath.setDocumentPath( file.getAbsolutePath() );
       documentPath.addToIndexes();
+
       LOGGER.info( "Finished Reading." );
    }
 

Modified: ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cr/JCasBuilder.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cr/JCasBuilder.java?rev=1876808&r1=1876807&r2=1876808&view=diff
==============================================================================
--- ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cr/JCasBuilder.java (original)
+++ ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/cr/JCasBuilder.java Wed
Apr 22 02:34:29 2020
@@ -55,12 +55,19 @@ final public class JCasBuilder {
    private String _docSubType = "";
    private String _docStandard = "";
    private int _docRevisionNum = 1;
-   private String _docTime = DATE_FORMAT.format( System.currentTimeMillis() );
+   private String _docTime = ""; //DATE_FORMAT.format( System.currentTimeMillis() );
    private String _docPath = "";
 
 
    private String _docText = "";
 
+   private boolean _overwrite = false;
+
+
+   public JCasBuilder overwrite() {
+      _overwrite = true;
+      return this;
+   }
 
    public JCasBuilder setInstitutionId( final String institutionId ) {
       _institutionId = institutionId;
@@ -184,11 +191,24 @@ final public class JCasBuilder {
     * @param jCas ye olde ...
     * @return a jcas  that has been reset (emptied of previous information) and populated
with data added in this builder.
     */
-   public JCas build( final JCas jCas ) {
+   public JCas rebuild( final JCas jCas ) {
       jCas.reset();
       return populate( jCas );
    }
 
+   private boolean ifWrite( final String value, final String defaultValue ) {
+      return _overwrite || !value.equals( defaultValue );
+   }
+
+   private boolean ifWrite( final int value, final int defaultValue ) {
+      return _overwrite || value != defaultValue;
+   }
+
+   private boolean ifWrite( final long value, final long defaultValue ) {
+      return _overwrite || value != defaultValue;
+   }
+
+
    /**
     * @param jCas ye olde ...
     * @return the given jcas populated with the data added in this builder.
@@ -196,45 +216,86 @@ final public class JCasBuilder {
    public JCas populate( final JCas jCas ) {
       final Metadata metadata = SourceMetadataUtil.getOrCreateMetadata( jCas );
 
-      SourceMetadataUtil.setPatientIdentifier( jCas, _patientId );
-      metadata.setPatientID( _patientNum );
+      if ( ifWrite( _patientId, SourceMetadataUtil.UNKNOWN_PATIENT ) ) {
+         SourceMetadataUtil.setPatientIdentifier( jCas, _patientId );
+      }
+      if ( ifWrite( _patientNum, SourceMetadataUtil.UNKNOWN_PATIENT_NUM ) ) {
+         metadata.setPatientID( _patientNum );
+      }
 
       final Demographics demographics = new Demographics( jCas );
       metadata.setDemographics( demographics );
-      demographics.setFirstName( _firstName );
-      demographics.setMiddleName( _middleName );
-      demographics.setLastName( _lastName );
-      demographics.setBirthDate( _birthday );
-      demographics.setDeathDate( _deathday );
-      demographics.setGender( _gender );
+      if ( ifWrite( _firstName, UNKNOWN ) ) {
+         demographics.setFirstName( _firstName );
+      }
+      if ( ifWrite( _middleName, UNKNOWN ) ) {
+         demographics.setMiddleName( _middleName );
+      }
+      if ( ifWrite( _lastName, UNKNOWN ) ) {
+         demographics.setLastName( _lastName );
+      }
+      if ( ifWrite( _birthday, UNKNOWN_DATE ) ) {
+         demographics.setBirthDate( _birthday );
+      }
+      if ( ifWrite( _deathday, UNKNOWN_DATE ) ) {
+         demographics.setDeathDate( _deathday );
+      }
+      if ( ifWrite( _gender, UNKNOWN_GENDER ) ) {
+         demographics.setGender( _gender );
+      }
 
       final SourceData sourceData = SourceMetadataUtil.getOrCreateSourceData( jCas );
-      sourceData.setSourceInstitution( _institutionId );
-      sourceData.setAuthorSpecialty( _authorSpecialty );
-
-      sourceData.setSourceEncounterId( _encounterId );
-      sourceData.setSourceInstanceId( _instanceId );
-
-      final DocumentID documentId = new DocumentID( jCas );
-      documentId.setDocumentID( _docId );
-      documentId.addToIndexes();
-
-      final DocumentIdPrefix documentIdPrefix = new DocumentIdPrefix( jCas );
-      documentIdPrefix.setDocumentIdPrefix( _docIdPrefix );
-      documentIdPrefix.addToIndexes();
-
-      sourceData.setNoteTypeCode( _docType );
-      sourceData.setNoteSubTypeCode( _docSubType );
-      sourceData.setDocumentStandard( _docStandard );
-
-      sourceData.setSourceRevisionDate( _docTime );
-      sourceData.setSourceRevisionNbr( _docRevisionNum );
-
-      final DocumentPath documentPath = new DocumentPath( jCas );
-      documentPath.setDocumentPath( _docPath );
-      documentPath.addToIndexes();
-
-      jCas.setDocumentText( _docText );
+      if ( ifWrite( _institutionId, UNKNOWN ) ) {
+         sourceData.setSourceInstitution( _institutionId );
+      }
+      if ( ifWrite( _authorSpecialty, UNKNOWN ) ) {
+         sourceData.setAuthorSpecialty( _authorSpecialty );
+      }
+      if ( ifWrite( _encounterId, "" ) ) {
+         sourceData.setSourceEncounterId( _encounterId );
+      }
+      if ( ifWrite( _instanceId, UNKNOWN ) ) {
+         sourceData.setSourceInstanceId( _instanceId );
+      }
+
+      if ( ifWrite( _docId, DocumentIDAnnotationUtil.NO_DOCUMENT_ID ) ) {
+         final DocumentID documentId = new DocumentID( jCas );
+         documentId.setDocumentID( _docId );
+         documentId.addToIndexes();
+      }
+
+      if ( ifWrite( _docIdPrefix, DocumentIDAnnotationUtil.NO_DOCUMENT_ID_PREFIX ) ) {
+         final DocumentIdPrefix documentIdPrefix = new DocumentIdPrefix( jCas );
+         documentIdPrefix.setDocumentIdPrefix( _docIdPrefix );
+         documentIdPrefix.addToIndexes();
+      }
+
+      if ( ifWrite( _docType, NoteSpecs.ID_NAME_CLINICAL_NOTE ) ) {
+         sourceData.setNoteTypeCode( _docType );
+      }
+      if ( ifWrite( _docSubType, "" ) ) {
+         sourceData.setNoteSubTypeCode( _docSubType );
+      }
+      if ( ifWrite( _docStandard, "" ) ) {
+         sourceData.setDocumentStandard( _docStandard );
+      }
+
+      if ( ifWrite( _docTime, "" ) ) {
+         sourceData.setSourceRevisionDate( _docTime );
+      }
+      if ( ifWrite( _docRevisionNum, 1 ) ) {
+         sourceData.setSourceRevisionNbr( _docRevisionNum );
+      }
+
+      if ( ifWrite( _docPath, "" ) ) {
+         final DocumentPath documentPath = new DocumentPath( jCas );
+         documentPath.setDocumentPath( _docPath );
+         documentPath.addToIndexes();
+      }
+
+      if ( ifWrite( _docText, "" ) ) {
+         jCas.setDocumentText( _docText );
+      }
 
       return jCas;
    }

Added: ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/util/IdentifiedAnnotationUtil.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/util/IdentifiedAnnotationUtil.java?rev=1876808&view=auto
==============================================================================
--- ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/util/IdentifiedAnnotationUtil.java
(added)
+++ ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/util/IdentifiedAnnotationUtil.java
Wed Apr 22 02:34:29 2020
@@ -0,0 +1,99 @@
+package org.apache.ctakes.core.util;
+
+
+import org.apache.ctakes.core.semantic.SemanticGroup;
+import org.apache.ctakes.core.semantic.SemanticTui;
+import org.apache.ctakes.typesystem.type.constants.CONST;
+import org.apache.ctakes.typesystem.type.refsem.UmlsConcept;
+import org.apache.ctakes.typesystem.type.textsem.IdentifiedAnnotation;
+
+import java.util.Collection;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * A one-stop shop for the most commonly requested Identified Annotation properties.
+ *
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 4/21/2020
+ */
+final public class IdentifiedAnnotationUtil {
+
+   private IdentifiedAnnotationUtil() {
+   }
+
+   /**
+    * @param annotation -
+    * @return true iff the annotation is not generic, not uncertain, not negated and not
conditional.
+    */
+   static public boolean isRealAffirmed( final IdentifiedAnnotation annotation ) {
+      return !isGeneric( annotation )
+             && !isUncertain( annotation )
+             && !isNegated( annotation )
+             && !isConditional( annotation );
+   }
+
+   static public boolean isGeneric( final IdentifiedAnnotation annotation ) {
+      return annotation.getGeneric();
+   }
+
+   static public boolean isUncertain( final IdentifiedAnnotation annotation ) {
+      return annotation.getUncertainty() == CONST.NE_UNCERTAINTY_PRESENT;
+   }
+
+   static public boolean isNegated( final IdentifiedAnnotation annotation ) {
+      return annotation.getPolarity() == CONST.NE_POLARITY_NEGATION_PRESENT;
+   }
+
+   static public boolean isConditional( final IdentifiedAnnotation annotation ) {
+      return annotation.getConditional();
+   }
+
+   static public String getText( final IdentifiedAnnotation annotation ) {
+      return annotation.getCoveredText();
+   }
+
+   static public boolean isHistoric( final IdentifiedAnnotation annotation ) {
+      return annotation.getHistoryOf() == CONST.NE_HISTORY_OF_PRESENT;
+   }
+
+   static public SemanticGroup getSemanticGroup( final IdentifiedAnnotation annotation )
{
+      return SemanticGroup.getBestGroup( annotation );
+   }
+
+   static public Collection<SemanticTui> getSemanticTui( final IdentifiedAnnotation
annotation ) {
+      return SemanticTui.getTuis( annotation );
+   }
+
+   static public Collection<String> getCuis( final IdentifiedAnnotation annotation
) {
+      return OntologyConceptUtil.getCuis( annotation );
+   }
+
+   /**
+    * @param annotation -
+    * @return a collection of schemes with codes for the given annotation.  e.g. snomed_us,
rxnorm.
+    */
+   static public Collection<String> getCodeSchemes( final IdentifiedAnnotation annotation
) {
+      return OntologyConceptUtil.getSchemeCodes( annotation ).keySet();
+   }
+
+   /**
+    * @param annotation -
+    * @param schemeName the name of a coding scheme.  e.g. snomed_us, rxnorm.
+    * @return all annotation codes for the given coding scheme.
+    */
+   static public Collection<String> getCodes( final IdentifiedAnnotation annotation,
final String schemeName ) {
+      return OntologyConceptUtil.getCodes( annotation, schemeName );
+   }
+
+   static public Collection<String> getPreferredText( final IdentifiedAnnotation annotation
) {
+      return OntologyConceptUtil.getUmlsConceptStream( annotation )
+                                .map( UmlsConcept::getPreferredText )
+                                .filter( Objects::nonNull )
+                                .filter( t -> !t.isEmpty() )
+                                .collect( Collectors.toSet() );
+   }
+
+
+}

Modified: ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/util/StringUtil.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/util/StringUtil.java?rev=1876808&r1=1876807&r2=1876808&view=diff
==============================================================================
--- ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/util/StringUtil.java (original)
+++ ctakes/trunk/ctakes-core/src/main/java/org/apache/ctakes/core/util/StringUtil.java Wed
Apr 22 02:34:29 2020
@@ -29,7 +29,7 @@ final public class StringUtil {
       if ( nextSplit < 0 ) {
          return new String[]{ line };
       }
-      final String[] tokens = new String[ line.length() / 2 + 1 ];
+      final String[] tokens = new String[ line.length() + 1 ];
       int index = 0;
       int lastSplit = -1;
       while ( nextSplit >= 0 ) {

Modified: ctakes/trunk/ctakes-examples/pom.xml
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-examples/pom.xml?rev=1876808&r1=1876807&r2=1876808&view=diff
==============================================================================
--- ctakes/trunk/ctakes-examples/pom.xml (original)
+++ ctakes/trunk/ctakes-examples/pom.xml Wed Apr 22 02:34:29 2020
@@ -59,6 +59,12 @@
      	<groupId>org.apache.uima</groupId>
      	<artifactId>uimafit-cpe</artifactId>
      </dependency>
+     <dependency>
+        <groupId>org.junit.jupiter</groupId>
+        <artifactId>junit-jupiter</artifactId>
+        <version>RELEASE</version>
+        <scope>compile</scope>
+     </dependency>
   </dependencies>
     <profiles>
         <profile>
@@ -96,5 +102,40 @@
                 </plugins>
             </build>
         </profile>
+       <profile>
+          <id>runDictionaryGui</id>
+          <activation>
+             <property>
+                <name>runDictionaryGui</name>
+             </property>
+          </activation>
+          <build>
+             <plugins>
+                <plugin>
+                   <groupId>org.codehaus.mojo</groupId>
+                   <artifactId>exec-maven-plugin</artifactId>
+                   <executions>
+                      <execution>
+                         <goals>
+                            <goal>exec</goal>
+                         </goals>
+                      </execution>
+                   </executions>
+                   <configuration>
+                      <executable>java</executable>
+                      <includeProjectDependencies>true</includeProjectDependencies>
+                      <includePluginDependencies>true</includePluginDependencies>
+                      <workingDirectory>${project.parent.basedir}</workingDirectory>
+                      <arguments>
+                         <argument>-classpath</argument>
+                         <classpath/>
+                         <argument>-Xmx3G</argument>
+                         <argument>org.apache.ctakes.gui.dictionary.DictionaryCreator</argument>
+                      </arguments>
+                   </configuration>
+                </plugin>
+             </plugins>
+          </build>
+       </profile>
     </profiles>
 </project>

Added: ctakes/trunk/ctakes-examples/src/main/java/org/apache/ctakes/examples/pipeline/PiperCreatorGui.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-examples/src/main/java/org/apache/ctakes/examples/pipeline/PiperCreatorGui.java?rev=1876808&view=auto
==============================================================================
--- ctakes/trunk/ctakes-examples/src/main/java/org/apache/ctakes/examples/pipeline/PiperCreatorGui.java
(added)
+++ ctakes/trunk/ctakes-examples/src/main/java/org/apache/ctakes/examples/pipeline/PiperCreatorGui.java
Wed Apr 22 02:34:29 2020
@@ -0,0 +1,24 @@
+package org.apache.ctakes.examples.pipeline;
+
+
+import org.apache.ctakes.gui.pipeline.PiperCreator;
+
+/**
+ * This is an alternative entry to the PiperCreator in ctakes-gui.
+ * In a developer environment the PiperCreator may not have all the available Pipe Bits in
the classpath.
+ * The ctakes-examples classpath should make them all available.
+ *
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 11/9/2019
+ */
+final public class PiperCreatorGui {
+
+   private PiperCreatorGui() {
+   }
+
+   public static void main( final String... args ) {
+      PiperCreator.main( args );
+   }
+
+}

Added: ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/CtakesTypeCreator.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/CtakesTypeCreator.java?rev=1876808&view=auto
==============================================================================
--- ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/CtakesTypeCreator.java
(added)
+++ ctakes/trunk/ctakes-fhir/src/main/java/org/apache/ctakes/fhir/resource/CtakesTypeCreator.java
Wed Apr 22 02:34:29 2020
@@ -0,0 +1,196 @@
+package org.apache.ctakes.fhir.resource;
+
+import org.apache.ctakes.core.semantic.SemanticGroup;
+import org.apache.ctakes.core.util.EssentialAnnotationUtil;
+import org.apache.ctakes.core.util.IdentifiedAnnotationUtil;
+import org.apache.ctakes.fhir.element.FhirElementFactory;
+import org.apache.ctakes.fhir.util.FhirNoteSpecs;
+import org.apache.ctakes.typesystem.type.textsem.EventMention;
+import org.apache.ctakes.typesystem.type.textsem.IdentifiedAnnotation;
+import org.apache.uima.jcas.JCas;
+import org.apache.uima.jcas.tcas.Annotation;
+import org.hl7.fhir.dstu3.model.*;
+
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+
+/**
+ * Creates fhir domain resources of specific types determined by ctakes semantic grouping.
+ *
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 4/21/2020
+ */
+final public class CtakesTypeCreator implements FhirResourceCreator<IdentifiedAnnotation,
DomainResource> {
+
+   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";
+
+
+   /**
+    * Creates fhir domain resources of specific types determined by ctakes semantic grouping.
+    *
+    * @param jCas ye olde ...
+    * @return begin offset sorted list of FHIR DomainResources for identified annotations
in jcas.
+    */
+   static public List<DomainResource> createTypeSystemResources( final JCas jCas )
{
+      final CtakesTypeCreator creator = new CtakesTypeCreator();
+
+      final FhirNoteSpecs noteSpecs = new FhirNoteSpecs( jCas );
+      final FhirPractitioner practitioner = PractitionerCtakes.getInstance();
+
+      final Map<IdentifiedAnnotation, Collection<Integer>> markableCorefs
+            = EssentialAnnotationUtil.createMarkableCorefs( jCas );
+
+      return EssentialAnnotationUtil.getRequiredAnnotations( jCas, markableCorefs )
+                                    .stream()
+                                    .sorted( Comparator.comparingInt( Annotation::getBegin
) )
+                                    .map( a -> creator.createResource( jCas, a, practitioner,
noteSpecs ) )
+                                    .collect( Collectors.toList() );
+   }
+
+   /**
+    * Creates fhir domain resource of a specific type determined by ctakes semantic grouping.
+    *
+    * @param jCas         ye olde ...
+    * @param annotation   -
+    * @param practitioner -
+    * @param noteSpecs    -
+    * @return FHIR DomainResource for identified annotation.
+    */
+   public DomainResource createResource( final JCas jCas,
+                                         final IdentifiedAnnotation annotation,
+                                         final FhirPractitioner practitioner,
+                                         final FhirNoteSpecs noteSpecs ) {
+      final Reference practitionerRef = practitioner.getPractitionerReference();
+      final Reference subjectRef = noteSpecs.getSubjectReference( annotation.getSubject()
);
+      final DomainResource resource = createDomainResource( annotation, practitionerRef,
subjectRef );
+      final String id
+            = FhirElementFactory.createId( jCas, resource.getClass().getSimpleName(), annotation.hashCode()
);
+      resource.setId( id );
+      // Add text span as an extension.
+      resource.addExtension( FhirElementFactory.createSpanBegin( annotation ) );
+      resource.addExtension( FhirElementFactory.createSpanEnd( annotation ) );
+      // Add DocTimeRel as an extension.
+      if ( annotation instanceof EventMention ) {
+         final Extension dtr = FhirElementFactory.createDocTimeRel( (EventMention)annotation
);
+         if ( dtr != null ) {
+            resource.addExtension( dtr );
+         }
+      }
+      // Add generic, uncertainty, negation as modifier extensions.
+      if ( IdentifiedAnnotationUtil.isGeneric( annotation ) ) {
+         resource.addModifierExtension( FhirElementFactory.createTrueExtension( GENERIC_EXT
) );
+      }
+      if ( IdentifiedAnnotationUtil.isUncertain( annotation ) ) {
+         resource.addModifierExtension( FhirElementFactory.createTrueExtension( UNCERTAIN_EXT
) );
+      }
+      if ( IdentifiedAnnotationUtil.isNegated( annotation ) ) {
+         resource.addModifierExtension( FhirElementFactory.createTrueExtension( NEGATED_EXT
) );
+      }
+      // Add history of as a modifier extension.
+      if ( IdentifiedAnnotationUtil.isHistoric( annotation ) ) {
+         resource.addModifierExtension( FhirElementFactory.createTrueExtension( HISTORIC_EXT
) );
+      }
+      return resource;
+   }
+
+
+   static private DomainResource createDomainResource( final IdentifiedAnnotation annotation,
+                                                       final Reference practitioner,
+                                                       final Reference subject ) {
+      final SemanticGroup group = SemanticGroup.getBestGroup( annotation );
+      switch ( group ) {
+         // Drug can also be Medication if it is general.  Immunization if known or NutritionOrder.
+         case DRUG:
+            return createDrug( annotation, practitioner, subject );
+         // Can also be AdverseEvent, AllergyIntolerance.
+         case DISORDER:
+            return createCondition( annotation, practitioner, subject );
+         // Can also be DetectedIssue.
+         case PROCEDURE:
+            return createProcedure( annotation, practitioner, subject );
+         // May become BodyStructure instead of BodySite.
+         case ANATOMY:
+            return createBodySite( annotation, practitioner, subject );
+         // May become ClinicalAttribute.
+         case FINDING:
+         case CLINICAL_ATTRIBUTE:
+         case LAB:
+            return createObservation( annotation, practitioner, subject );
+      }
+      return new Basic()
+            .setCode( FhirElementFactory.createPrimaryCode( annotation ) )
+            .setAuthor( practitioner )
+            .setSubject( subject );
+   }
+
+
+   static private MedicationStatement createDrug( final IdentifiedAnnotation annotation,
+                                                  final Reference practitioner,
+                                                  final Reference subject ) {
+      MedicationStatement.MedicationStatementStatus status = MedicationStatement.MedicationStatementStatus.NULL;
+      if ( IdentifiedAnnotationUtil.isHistoric( annotation ) ) {
+         status = MedicationStatement.MedicationStatementStatus.STOPPED;
+      } else if ( IdentifiedAnnotationUtil.isRealAffirmed( annotation ) ) {
+         status = MedicationStatement.MedicationStatementStatus.ACTIVE;
+      }
+      return new MedicationStatement()
+            .setMedication( FhirElementFactory.createPrimaryCode( annotation ) )
+            .setStatus( status )
+            .setInformationSource( practitioner )
+            .setSubject( subject );
+   }
+
+   static private Condition createCondition( final IdentifiedAnnotation annotation,
+                                             final Reference practitioner,
+                                             final Reference subject ) {
+      return new Condition()
+            .setCode( FhirElementFactory.createPrimaryCode( annotation ) )
+            .setAsserter( practitioner )
+            .setSubject( subject );
+   }
+
+   static private Observation createObservation( final IdentifiedAnnotation annotation,
+                                                 final Reference practitioner,
+                                                 final Reference subject ) {
+      return new Observation()
+            .setCode( FhirElementFactory.createPrimaryCode( annotation ) )
+            .setStatus( Observation.ObservationStatus.UNKNOWN )
+            .addPerformer( practitioner )
+            .setSubject( subject );
+   }
+
+   static private Procedure createProcedure( final IdentifiedAnnotation annotation,
+                                             final Reference practitioner,
+                                             final Reference subject ) {
+      Procedure.ProcedureStatus status = Procedure.ProcedureStatus.UNKNOWN;
+      if ( IdentifiedAnnotationUtil.isHistoric( annotation ) ) {
+         status = Procedure.ProcedureStatus.COMPLETED;
+      } else if ( IdentifiedAnnotationUtil.isRealAffirmed( annotation ) ) {
+         status = Procedure.ProcedureStatus.INPROGRESS;
+      }
+      // There is no author / reporter / recorder / asserter in hapi.
+      return new Procedure()
+            .setCode( FhirElementFactory.createPrimaryCode( annotation ) )
+            .setStatus( status )
+            .setSubject( subject );
+   }
+
+   static private BodySite createBodySite( final IdentifiedAnnotation annotation,
+                                           final Reference practitioner,
+                                           final Reference subject ) {
+      // There is no author / reporter / recorder / asserter / information source in hapi.
+      return new BodySite()
+            .setCode( FhirElementFactory.createPrimaryCode( annotation ) )
+            .setPatient( subject );
+   }
+
+
+}



Mime
View raw message