You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ctakes.apache.org by cl...@apache.org on 2014/10/28 22:01:07 UTC

svn commit: r1634983 [1/3] - in /ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal: ae/ ae/feature/ eval/ pipelines/

Author: clin
Date: Tue Oct 28 21:01:06 2014
New Revision: 1634983

URL: http://svn.apache.org/r1634983
Log:
the latest event-time event-event evaluation code and Annotator
Add self-training annotator for event-time relation  

Added:
    ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/EventTimeSelfRelationAnnotator.java
    ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/eval/EvaluationOfEventEventThymeRelations.java
    ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/eval/EvaluationOfSelfEventTimeRelations.java
Modified:
    ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/EventEventRelationAnnotator.java
    ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/EventTimeRelationAnnotator.java
    ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/feature/CheckSpecialWordRelationExtractor.java
    ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/feature/EventTimeRelationFeatureExtractor.java
    ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/feature/NumberOfEventsInTheSameSentenceExtractor.java
    ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/eval/EvaluationOfEventTimeRelations.java
    ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/eval/EvaluationOfTemporalRelations.java
    ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/eval/EvaluationOfTemporalRelations_ImplBase.java
    ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/pipelines/FullTemporalExtractionPipeline.java

Modified: ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/EventEventRelationAnnotator.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/EventEventRelationAnnotator.java?rev=1634983&r1=1634982&r2=1634983&view=diff
==============================================================================
--- ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/EventEventRelationAnnotator.java (original)
+++ ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/EventEventRelationAnnotator.java Tue Oct 28 21:01:06 2014
@@ -21,6 +21,7 @@ package org.apache.ctakes.temporal.ae;
 import java.io.File;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 
@@ -29,14 +30,35 @@ import org.apache.ctakes.relationextract
 import org.apache.ctakes.relationextractor.ae.features.RelationFeaturesExtractor;
 import org.apache.ctakes.relationextractor.ae.features.TokenFeaturesExtractor;
 import org.apache.ctakes.temporal.ae.feature.CheckSpecialWordRelationExtractor;
+import org.apache.ctakes.temporal.ae.feature.ConjunctionRelationFeaturesExtractor;
+//import org.apache.ctakes.temporal.ae.feature.DependencyParseUtils;
 import org.apache.ctakes.temporal.ae.feature.DependencyPathFeaturesExtractor;
+import org.apache.ctakes.temporal.ae.feature.CoordinateFeaturesExtractor;
+import org.apache.ctakes.temporal.ae.feature.DependingVerbsFeatureExtractor;
+//import org.apache.ctakes.temporal.ae.feature.EventInBetweenPropertyExtractor;
+//import org.apache.ctakes.temporal.ae.feature.EventOutsidePropertyExtractor;
+import org.apache.ctakes.temporal.ae.feature.SpecialAnnotationRelationExtractor;
+import org.apache.ctakes.temporal.ae.feature.TemporalPETFlatExtractor;
+import org.apache.ctakes.temporal.ae.feature.TokenPropertyFeaturesExtractor;
+import org.apache.ctakes.temporal.ae.feature.DeterminerRelationFeaturesExtractor;
 import org.apache.ctakes.temporal.ae.feature.EventArgumentPropertyExtractor;
+import org.apache.ctakes.temporal.ae.feature.EventTimeRelationFeatureExtractor;
+import org.apache.ctakes.temporal.ae.feature.EventPositionRelationFeaturesExtractor;
+import org.apache.ctakes.temporal.ae.feature.NumberOfEventsInTheSameSentenceExtractor;
 import org.apache.ctakes.temporal.ae.feature.NearbyVerbTenseRelationExtractor;
+import org.apache.ctakes.temporal.ae.feature.NumberOfEventTimeBetweenCandidatesExtractor;
+import org.apache.ctakes.temporal.ae.feature.OverlappedHeadFeaturesExtractor;
+import org.apache.ctakes.temporal.ae.feature.SRLRelationFeaturesExtractor;
+import org.apache.ctakes.temporal.ae.feature.TimeXRelationFeaturesExtractor;
 import org.apache.ctakes.temporal.ae.feature.SectionHeaderRelationExtractor;
+//import org.apache.ctakes.temporal.ae.feature.TemporalAttributeFeatureExtractor;
 import org.apache.ctakes.temporal.ae.feature.UmlsFeatureExtractor;
+//import org.apache.ctakes.temporal.ae.feature.UnexpandedTokenFeaturesExtractor;
+//import org.apache.ctakes.temporal.ae.feature.treekernel.TemporalPETExtractor;
 import org.apache.ctakes.typesystem.type.relation.BinaryTextRelation;
 import org.apache.ctakes.typesystem.type.relation.RelationArgument;
 import org.apache.ctakes.typesystem.type.relation.TemporalTextRelation;
+//import org.apache.ctakes.typesystem.type.syntax.ConllDependencyNode;
 import org.apache.ctakes.typesystem.type.textsem.EventMention;
 import org.apache.ctakes.typesystem.type.textsem.IdentifiedAnnotation;
 import org.apache.ctakes.typesystem.type.textspan.Sentence;
@@ -56,61 +78,80 @@ import com.google.common.collect.Lists;
 
 public class EventEventRelationAnnotator extends RelationExtractorAnnotator {
 
-	  public static AnalysisEngineDescription createDataWriterDescription(
-		      Class<? extends DataWriter<String>> dataWriterClass,
-		      File outputDirectory,
-		      double probabilityOfKeepingANegativeExample) throws ResourceInitializationException {
-		    return AnalysisEngineFactory.createEngineDescription(
-		            EventEventRelationAnnotator.class,
-		            CleartkAnnotator.PARAM_IS_TRAINING,
-		            true,
-		            DefaultDataWriterFactory.PARAM_DATA_WRITER_CLASS_NAME,
-		            dataWriterClass,
-		            DirectoryDataWriterFactory.PARAM_OUTPUT_DIRECTORY,
-		            outputDirectory,
-		            RelationExtractorAnnotator.PARAM_PROBABILITY_OF_KEEPING_A_NEGATIVE_EXAMPLE,
-		            // not sure why this has to be cast; something funny going on in uimaFIT maybe?
-		            (float) probabilityOfKeepingANegativeExample);
-		      }
-	  
-	  public static AnalysisEngineDescription createAnnotatorDescription(String modelPath)
-		      throws ResourceInitializationException {
-		    return AnalysisEngineFactory.createEngineDescription(
-		        EventEventRelationAnnotator.class,
-		        CleartkAnnotator.PARAM_IS_TRAINING,
-		        false,
-		        GenericJarClassifierFactory.PARAM_CLASSIFIER_JAR_PATH,
-		        modelPath);
-		  }
-	  
-	  /**
-	   * @deprecated use String path instead of File.
-	   * ClearTK will automatically Resolve the String to an InputStream.
-	   * This will allow resources to be read within from a jar as well as File.  
-	   */	  
-	  public static AnalysisEngineDescription createAnnotatorDescription(File modelDirectory)
-		      throws ResourceInitializationException {
-		    return AnalysisEngineFactory.createEngineDescription(
-		        EventEventRelationAnnotator.class,
-		        CleartkAnnotator.PARAM_IS_TRAINING,
-		        false,
-		        GenericJarClassifierFactory.PARAM_CLASSIFIER_JAR_PATH,
-		        new File(modelDirectory, "model.jar"));
-		  }
-
-	  @Override
-	  protected List<RelationFeaturesExtractor> getFeatureExtractors() {
-	    return Lists.newArrayList(
-	    						  new TokenFeaturesExtractor()
-	    						, new PartOfSpeechFeaturesExtractor()
-//	    						, new EventArgumentPropertyExtractor()
-	    						, new SectionHeaderRelationExtractor()
-	    						, new NearbyVerbTenseRelationExtractor()
-	    						, new CheckSpecialWordRelationExtractor()
-	    						, new UmlsFeatureExtractor()
-	    						, new DependencyPathFeaturesExtractor()
-	    						);
-	  }
+	public static AnalysisEngineDescription createDataWriterDescription(
+			Class<? extends DataWriter<String>> dataWriterClass,
+					File outputDirectory,
+					double probabilityOfKeepingANegativeExample) throws ResourceInitializationException {
+		return AnalysisEngineFactory.createEngineDescription(
+				EventEventRelationAnnotator.class,
+				CleartkAnnotator.PARAM_IS_TRAINING,
+				true,
+				DefaultDataWriterFactory.PARAM_DATA_WRITER_CLASS_NAME,
+				dataWriterClass,
+				DirectoryDataWriterFactory.PARAM_OUTPUT_DIRECTORY,
+				outputDirectory,
+				RelationExtractorAnnotator.PARAM_PROBABILITY_OF_KEEPING_A_NEGATIVE_EXAMPLE,
+				// not sure why this has to be cast; something funny going on in uimaFIT maybe?
+				(float) probabilityOfKeepingANegativeExample);
+	}
+
+	public static AnalysisEngineDescription createAnnotatorDescription(String modelPath)
+			throws ResourceInitializationException {
+		return AnalysisEngineFactory.createEngineDescription(
+				EventEventRelationAnnotator.class,
+				CleartkAnnotator.PARAM_IS_TRAINING,
+				false,
+				GenericJarClassifierFactory.PARAM_CLASSIFIER_JAR_PATH,
+				modelPath);
+	}
+
+	/**
+	 * @deprecated use String path instead of File.
+	 * ClearTK will automatically Resolve the String to an InputStream.
+	 * This will allow resources to be read within from a jar as well as File.  
+	 */	  
+	@SuppressWarnings("dep-ann")
+	public static AnalysisEngineDescription createAnnotatorDescription(File modelDirectory)
+			throws ResourceInitializationException {
+		return AnalysisEngineFactory.createEngineDescription(
+				EventEventRelationAnnotator.class,
+				CleartkAnnotator.PARAM_IS_TRAINING,
+				false,
+				GenericJarClassifierFactory.PARAM_CLASSIFIER_JAR_PATH,
+				new File(modelDirectory, "model.jar"));
+	}
+
+	@Override
+	protected List<RelationFeaturesExtractor> getFeatureExtractors() {
+		return Lists.newArrayList(
+				new TokenFeaturesExtractor()
+				//				new UnexpandedTokenFeaturesExtractor() //use unexpanded version for i2b2 data
+				, new PartOfSpeechFeaturesExtractor()
+				//	    		, new TemporalPETExtractor()
+				, new EventArgumentPropertyExtractor()
+				, new NumberOfEventTimeBetweenCandidatesExtractor()
+				, new SectionHeaderRelationExtractor()
+				, new NearbyVerbTenseRelationExtractor()
+				, new CheckSpecialWordRelationExtractor()
+				, new UmlsFeatureExtractor()
+				, new DependencyPathFeaturesExtractor()
+				, new CoordinateFeaturesExtractor()
+				, new OverlappedHeadFeaturesExtractor()
+				, new SRLRelationFeaturesExtractor()
+				, new NumberOfEventsInTheSameSentenceExtractor()
+				, new EventPositionRelationFeaturesExtractor() //not helpful
+				, new TimeXRelationFeaturesExtractor() //not helpful
+				, new ConjunctionRelationFeaturesExtractor()
+				, new DeterminerRelationFeaturesExtractor()
+				, new EventTimeRelationFeatureExtractor()
+				, new TokenPropertyFeaturesExtractor()
+				, new DependingVerbsFeatureExtractor()
+				, new SpecialAnnotationRelationExtractor() //not helpful
+				, new TemporalPETFlatExtractor()
+				//				, new EventInBetweenPropertyExtractor()
+				//				, new EventOutsidePropertyExtractor()
+				);
+	}
 
 	@Override
 	protected Class<? extends Annotation> getCoveringClass() {
@@ -120,18 +161,74 @@ public class EventEventRelationAnnotator
 	@Override
 	protected List<IdentifiedAnnotationPair> getCandidateRelationArgumentPairs(
 			JCas jCas, Annotation sentence) {
-	    List<IdentifiedAnnotationPair> pairs = Lists.newArrayList();
-	    List<EventMention> events = new ArrayList<EventMention>(JCasUtil.selectCovered(jCas, EventMention.class, sentence));
-	    for (int i = 0; i < events.size(); i++){
-	      if(!events.get(i).getClass().equals(EventMention.class)) continue;
-	    	for(int j = i+1; j < events.size(); j++){
-	    	  if(!events.get(j).getClass().equals(EventMention.class)) continue;
-	        pairs.add(new IdentifiedAnnotationPair(events.get(i), events.get(j)));
-	    	}
-	    }
-	    return pairs;
+		
+		Map<EventMention, Collection<EventMention>> coveringMap =
+				JCasUtil.indexCovering(jCas, EventMention.class, EventMention.class);
+		
+		List<IdentifiedAnnotationPair> pairs = Lists.newArrayList();
+		List<EventMention> events = new ArrayList<>(JCasUtil.selectCovered(jCas, EventMention.class, sentence));
+		//filter events:
+		List<EventMention> realEvents = Lists.newArrayList();
+		for( EventMention event : events){
+			if(event.getClass().equals(EventMention.class)){
+				realEvents.add(event);
+			}
+		}
+		events = realEvents;
+
+		int eventNum = events.size();
+
+		for (int i = 0; i < eventNum-1; i++){
+			for(int j = i+1; j < eventNum; j++){
+				EventMention eventA = events.get(j);
+				EventMention eventB = events.get(i);
+				boolean eventAValid = false;
+				boolean eventBValid = false;
+				for (EventMention event : JCasUtil.selectCovered(jCas, EventMention.class, eventA)){
+					if(!event.getClass().equals(EventMention.class)){
+						eventAValid = true;
+						break;
+					}
+				}
+				for (EventMention event : JCasUtil.selectCovered(jCas, EventMention.class, eventB)){
+					if(!event.getClass().equals(EventMention.class)){
+						eventBValid = true;
+						break;
+					}
+				}
+				if(eventAValid && eventBValid){
+					if(this.isTraining()){
+						for (EventMention event1 : coveringMap.get(eventA)){
+							for(EventMention event2 : coveringMap.get(eventB)){
+								pairs.add(new IdentifiedAnnotationPair(event1, event2));
+							}
+						}
+					}
+					pairs.add(new IdentifiedAnnotationPair(eventA, eventB));
+				}
+			}
+		}
+
+
+		//		if(eventNum >= 2){
+		//			for ( int i = 0; i< eventNum -1 ; i ++){
+		//				EventMention evI = events.get(i);
+		//				for(int j = i+1; j< eventNum; j++){
+		//					EventMention evJ = events.get(j);
+		//					if(j-i==1 || j-i==eventNum-1){//if two events are consecutive, or major events
+		//						pairs.add(new IdentifiedAnnotationPair(evJ, evI));
+		//					}else if(ifDependent(jCas, evI, evJ)){//if the event pairs are dependent// eventNum < 7 && 
+		//						pairs.add(new IdentifiedAnnotationPair(evJ, evI));
+		//					}else{// if the 
+		//						continue;
+		//					}
+		//				}
+		//			}
+		//		}
+
+		return pairs;
 	}
-	
+
 	@Override
 	protected void createRelation(JCas jCas, IdentifiedAnnotation arg1,
 			IdentifiedAnnotation arg2, String predictedCategory) {
@@ -149,7 +246,7 @@ public class EventEventRelationAnnotator
 		relation.setCategory(predictedCategory);
 		relation.addToIndexes();
 	}
-	
+
 	@Override
 	protected String getRelationCategory(
 			Map<List<Annotation>, BinaryTextRelation> relationLookup,
@@ -157,13 +254,18 @@ public class EventEventRelationAnnotator
 			IdentifiedAnnotation arg2) {
 		BinaryTextRelation relation = relationLookup.get(Arrays.asList(arg1, arg2));
 		String category = null;
-		if (relation != null) {
+		if (relation != null && relation instanceof TemporalTextRelation) {
 			category = relation.getCategory();
 		} else {
 			relation = relationLookup.get(Arrays.asList(arg2, arg1));
-			if (relation != null) {
+			if (relation != null && relation instanceof TemporalTextRelation) {
 				if(relation.getCategory().equals("OVERLAP")){
 					category = relation.getCategory();
+					//				}else if (relation.getCategory().equals("BEFORE")){
+					//					category = "AFTER";
+					//				}else if (relation.getCategory().equals("AFTER")){
+					//					category = "BEFORE";
+					//				}
 				}else{
 					category = relation.getCategory() + "-1";
 				}

Modified: ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/EventTimeRelationAnnotator.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/EventTimeRelationAnnotator.java?rev=1634983&r1=1634982&r2=1634983&view=diff
==============================================================================
--- ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/EventTimeRelationAnnotator.java (original)
+++ ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/EventTimeRelationAnnotator.java Tue Oct 28 21:01:06 2014
@@ -28,14 +28,29 @@ import org.apache.ctakes.relationextract
 import org.apache.ctakes.relationextractor.ae.features.RelationFeaturesExtractor;
 import org.apache.ctakes.relationextractor.ae.features.TokenFeaturesExtractor;
 import org.apache.ctakes.temporal.ae.feature.CheckSpecialWordRelationExtractor;
+import org.apache.ctakes.temporal.ae.feature.ConjunctionRelationFeaturesExtractor;
+import org.apache.ctakes.temporal.ae.feature.DependencyFeatureExtractor;
 import org.apache.ctakes.temporal.ae.feature.DependencyPathFeaturesExtractor;
+import org.apache.ctakes.temporal.ae.feature.EventArgumentPropertyExtractor;
+//import org.apache.ctakes.temporal.ae.feature.EventIndexOfSameSentenceRelationFeaturesExtractor;
+//import org.apache.ctakes.temporal.ae.feature.EventPositionRelationFeaturesExtractor;
+//import org.apache.ctakes.temporal.ae.feature.EventTimeRelationFeatureExtractor;
 import org.apache.ctakes.temporal.ae.feature.NearbyVerbTenseRelationExtractor;
 import org.apache.ctakes.temporal.ae.feature.NearestFlagFeatureExtractor;
-import org.apache.ctakes.temporal.ae.feature.SectionHeaderRelationExtractor;
+import org.apache.ctakes.temporal.ae.feature.NumberOfEventTimeBetweenCandidatesExtractor;
+import org.apache.ctakes.temporal.ae.feature.OverlappedHeadFeaturesExtractor;
+//import org.apache.ctakes.temporal.ae.feature.SRLRelationFeaturesExtractor;
+//import org.apache.ctakes.temporal.ae.feature.SectionHeaderRelationExtractor;
+import org.apache.ctakes.temporal.ae.feature.TemporalAttributeFeatureExtractor;
+import org.apache.ctakes.temporal.ae.feature.TemporalPETFlatExtractor;
+//import org.apache.ctakes.temporal.ae.feature.TimeWordTypeRelationExtractor;
+import org.apache.ctakes.temporal.ae.feature.TimeXPropertyRelationFeaturesExtractor;
+import org.apache.ctakes.temporal.ae.feature.TimeXRelationFeaturesExtractor;
+//import org.apache.ctakes.temporal.ae.feature.UnexpandedTokenFeaturesExtractor;
 //import org.apache.ctakes.temporal.ae.feature.TemporalAttributeFeatureExtractor;
 //import org.apache.ctakes.temporal.ae.feature.treekernel.EventTimeFlatTreeFeatureExtractor;
 //import org.apache.ctakes.temporal.ae.feature.treekernel.EventVerbRelationTreeExtractor;
-import org.apache.ctakes.temporal.ae.feature.treekernel.TemporalPETExtractor;
+//import org.apache.ctakes.temporal.ae.feature.treekernel.TemporalPETExtractor;
 //import org.apache.ctakes.temporal.ae.feature.treekernel.TemporalPathExtractor;
 import org.apache.ctakes.typesystem.type.relation.BinaryTextRelation;
 import org.apache.ctakes.typesystem.type.relation.RelationArgument;
@@ -77,7 +92,7 @@ public class EventTimeRelationAnnotator 
 				(float) probabilityOfKeepingANegativeExample);
 	}
 
-	public static AnalysisEngineDescription createAnnotatorDescription(String modelPath)
+	public static AnalysisEngineDescription createEngineDescription(String modelPath)
 			throws ResourceInitializationException {
 		return AnalysisEngineFactory.createEngineDescription(
 				EventTimeRelationAnnotator.class,
@@ -86,12 +101,13 @@ public class EventTimeRelationAnnotator 
 				GenericJarClassifierFactory.PARAM_CLASSIFIER_JAR_PATH,
 				modelPath);
 	}
-	  /**
-	   * @deprecated use String path instead of File.
-	   * ClearTK will automatically Resolve the String to an InputStream.
-	   * This will allow resources to be read within from a jar as well as File.  
-	   */	 
-	public static AnalysisEngineDescription createAnnotatorDescription(File modelDirectory)
+	/**
+	 * @deprecated use String path instead of File.
+	 * ClearTK will automatically Resolve the String to an InputStream.
+	 * This will allow resources to be read within from a jar as well as File.  
+	 */	 
+	@Deprecated
+	public static AnalysisEngineDescription createEngineDescription(File modelDirectory)
 			throws ResourceInitializationException {
 		return AnalysisEngineFactory.createEngineDescription(
 				EventTimeRelationAnnotator.class,
@@ -105,18 +121,31 @@ public class EventTimeRelationAnnotator 
 	protected List<RelationFeaturesExtractor> getFeatureExtractors() {
 		return Lists.newArrayList(
 				new TokenFeaturesExtractor()
+				//				new UnexpandedTokenFeaturesExtractor() //use unexpanded version for i2b2 data
 				, new PartOfSpeechFeaturesExtractor()
-				//    						, new TemporalAttributeFeatureExtractor()
+				, new TemporalAttributeFeatureExtractor()
 				//				, new EventTimeFlatTreeFeatureExtractor()
-				, new TemporalPETExtractor()
-				//				, new TemporalPathExtractor()
+				//				, new TemporalPETExtractor()
+				//, new TemporalPathExtractor()
 				//				, new EventVerbRelationTreeExtractor()
-				, new SectionHeaderRelationExtractor()
+				, new NumberOfEventTimeBetweenCandidatesExtractor()
+				//				, new SectionHeaderRelationExtractor()
 				, new NearbyVerbTenseRelationExtractor()
 				, new CheckSpecialWordRelationExtractor()
 				, new NearestFlagFeatureExtractor()
 				, new DependencyPathFeaturesExtractor()
-				//				, new DependencyFeatureExtractor()
+				, new DependencyFeatureExtractor()
+				//				, new SRLRelationFeaturesExtractor()// tried, but not helpful
+				, new EventArgumentPropertyExtractor()
+				, new OverlappedHeadFeaturesExtractor()
+				//				, new EventTimeRelationFeatureExtractor()
+				, new ConjunctionRelationFeaturesExtractor()
+				//				, new EventPositionRelationFeaturesExtractor() //tried, but not helpful
+				, new TimeXRelationFeaturesExtractor()
+				, new TemporalPETFlatExtractor()
+				, new TimeXPropertyRelationFeaturesExtractor()
+				//				, new TimeWordTypeRelationExtractor() //tried, but not helpful
+				//				, new EventIndexOfSameSentenceRelationFeaturesExtractor() //tried, but not helpful
 				);
 	}
 
@@ -133,9 +162,18 @@ public class EventTimeRelationAnnotator 
 		for (EventMention event : JCasUtil.selectCovered(jCas, EventMention.class, sentence)) {
 			// ignore subclasses like Procedure and Disease/Disorder
 			if (event.getClass().equals(EventMention.class)) {
-				for (TimeMention time : JCasUtil.selectCovered(jCas, TimeMention.class, sentence)) {
-					pairs.add(new IdentifiedAnnotationPair(event, time));
-				}
+//				boolean eventValid = false;
+//				for (EventMention ev : JCasUtil.selectCovered(jCas, EventMention.class, event)){
+//					if(!ev.getClass().equals(EventMention.class)){// if there is an valid UMLS type in the same span, then true
+//						eventValid = true;
+//						break;
+//					}
+//				}
+//				if(eventValid){
+					for (TimeMention time : JCasUtil.selectCovered(jCas, TimeMention.class, sentence)) {
+						pairs.add(new IdentifiedAnnotationPair(event, time));
+					}
+//				}
 			}
 		}
 
@@ -196,6 +234,11 @@ public class EventTimeRelationAnnotator 
 			if (relation != null) {
 				if(relation.getCategory().equals("OVERLAP")){
 					category = relation.getCategory();
+					//				}else if (relation.getCategory().equals("BEFORE")){
+					//					category = "AFTER";
+					//				}else if (relation.getCategory().equals("AFTER")){
+					//					category = "BEFORE";
+					//				}
 				}else{
 					category = relation.getCategory() + "-1";
 				}

Added: ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/EventTimeSelfRelationAnnotator.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/EventTimeSelfRelationAnnotator.java?rev=1634983&view=auto
==============================================================================
--- ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/EventTimeSelfRelationAnnotator.java (added)
+++ ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/EventTimeSelfRelationAnnotator.java Tue Oct 28 21:01:06 2014
@@ -0,0 +1,249 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ctakes.temporal.ae;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.ctakes.relationextractor.ae.RelationExtractorAnnotator;
+import org.apache.ctakes.relationextractor.ae.features.PartOfSpeechFeaturesExtractor;
+import org.apache.ctakes.relationextractor.ae.features.RelationFeaturesExtractor;
+import org.apache.ctakes.relationextractor.ae.features.TokenFeaturesExtractor;
+import org.apache.ctakes.temporal.ae.feature.CheckSpecialWordRelationExtractor;
+import org.apache.ctakes.temporal.ae.feature.ConjunctionRelationFeaturesExtractor;
+import org.apache.ctakes.temporal.ae.feature.DependencyFeatureExtractor;
+import org.apache.ctakes.temporal.ae.feature.DependencyPathFeaturesExtractor;
+import org.apache.ctakes.temporal.ae.feature.EventArgumentPropertyExtractor;
+//import org.apache.ctakes.temporal.ae.feature.EventIndexOfSameSentenceRelationFeaturesExtractor;
+//import org.apache.ctakes.temporal.ae.feature.EventPositionRelationFeaturesExtractor;
+//import org.apache.ctakes.temporal.ae.feature.EventTimeRelationFeatureExtractor;
+import org.apache.ctakes.temporal.ae.feature.NearbyVerbTenseRelationExtractor;
+import org.apache.ctakes.temporal.ae.feature.NearestFlagFeatureExtractor;
+import org.apache.ctakes.temporal.ae.feature.NumberOfEventTimeBetweenCandidatesExtractor;
+import org.apache.ctakes.temporal.ae.feature.OverlappedHeadFeaturesExtractor;
+//import org.apache.ctakes.temporal.ae.feature.SRLRelationFeaturesExtractor;
+//import org.apache.ctakes.temporal.ae.feature.SectionHeaderRelationExtractor;
+import org.apache.ctakes.temporal.ae.feature.TemporalAttributeFeatureExtractor;
+import org.apache.ctakes.temporal.ae.feature.TemporalPETFlatExtractor;
+//import org.apache.ctakes.temporal.ae.feature.TimeWordTypeRelationExtractor;
+import org.apache.ctakes.temporal.ae.feature.TimeXPropertyRelationFeaturesExtractor;
+import org.apache.ctakes.temporal.ae.feature.TimeXRelationFeaturesExtractor;
+//import org.apache.ctakes.temporal.ae.feature.UnexpandedTokenFeaturesExtractor;
+//import org.apache.ctakes.temporal.ae.feature.TemporalAttributeFeatureExtractor;
+//import org.apache.ctakes.temporal.ae.feature.treekernel.EventTimeFlatTreeFeatureExtractor;
+//import org.apache.ctakes.temporal.ae.feature.treekernel.EventVerbRelationTreeExtractor;
+//import org.apache.ctakes.temporal.ae.feature.treekernel.TemporalPETExtractor;
+//import org.apache.ctakes.temporal.ae.feature.treekernel.TemporalPathExtractor;
+import org.apache.ctakes.typesystem.type.relation.BinaryTextRelation;
+import org.apache.ctakes.typesystem.type.relation.RelationArgument;
+import org.apache.ctakes.typesystem.type.relation.TemporalTextRelation;
+import org.apache.ctakes.typesystem.type.textsem.EventMention;
+import org.apache.ctakes.typesystem.type.textsem.IdentifiedAnnotation;
+import org.apache.ctakes.typesystem.type.textsem.TimeMention;
+import org.apache.ctakes.typesystem.type.textspan.Sentence;
+import org.apache.uima.analysis_engine.AnalysisEngineDescription;
+import org.apache.uima.jcas.JCas;
+import org.apache.uima.jcas.tcas.Annotation;
+import org.apache.uima.resource.ResourceInitializationException;
+import org.cleartk.ml.CleartkAnnotator;
+import org.cleartk.ml.DataWriter;
+import org.cleartk.ml.jar.DefaultDataWriterFactory;
+import org.cleartk.ml.jar.DirectoryDataWriterFactory;
+import org.cleartk.ml.jar.GenericJarClassifierFactory;
+import org.apache.uima.fit.factory.AnalysisEngineFactory;
+import org.apache.uima.fit.util.JCasUtil;
+
+import com.google.common.collect.Lists;
+
+public class EventTimeSelfRelationAnnotator extends RelationExtractorAnnotator {
+
+	public static AnalysisEngineDescription createDataWriterDescription(
+			Class<? extends DataWriter<String>> dataWriterClass,
+					File outputDirectory,
+					double probabilityOfKeepingANegativeExample) throws ResourceInitializationException {
+		return AnalysisEngineFactory.createEngineDescription(
+				EventTimeSelfRelationAnnotator.class,
+				CleartkAnnotator.PARAM_IS_TRAINING,
+				true,
+				DefaultDataWriterFactory.PARAM_DATA_WRITER_CLASS_NAME,
+				dataWriterClass,
+				DirectoryDataWriterFactory.PARAM_OUTPUT_DIRECTORY,
+				outputDirectory,
+				RelationExtractorAnnotator.PARAM_PROBABILITY_OF_KEEPING_A_NEGATIVE_EXAMPLE,
+				// not sure why this has to be cast; something funny going on in uimaFIT maybe?
+				(float) probabilityOfKeepingANegativeExample);
+	}
+
+	public static AnalysisEngineDescription createEngineDescription(String modelPath)
+			throws ResourceInitializationException {
+		return AnalysisEngineFactory.createEngineDescription(
+				EventTimeSelfRelationAnnotator.class,
+				CleartkAnnotator.PARAM_IS_TRAINING,
+				false,
+				GenericJarClassifierFactory.PARAM_CLASSIFIER_JAR_PATH,
+				modelPath);
+	}
+	/**
+	 * @deprecated use String path instead of File.
+	 * ClearTK will automatically Resolve the String to an InputStream.
+	 * This will allow resources to be read within from a jar as well as File.  
+	 */	 
+	@Deprecated
+	public static AnalysisEngineDescription createEngineDescription(File modelDirectory)
+			throws ResourceInitializationException {
+		return AnalysisEngineFactory.createEngineDescription(
+				EventTimeSelfRelationAnnotator.class,
+				CleartkAnnotator.PARAM_IS_TRAINING,
+				false,
+				GenericJarClassifierFactory.PARAM_CLASSIFIER_JAR_PATH,
+				new File(modelDirectory, "model.jar"));
+	}
+
+	@Override
+	protected List<RelationFeaturesExtractor> getFeatureExtractors() {
+		return Lists.newArrayList(
+				new TokenFeaturesExtractor()
+				//				new UnexpandedTokenFeaturesExtractor() //use unexpanded version for i2b2 data
+				, new PartOfSpeechFeaturesExtractor()
+				, new TemporalAttributeFeatureExtractor()
+				//				, new EventTimeFlatTreeFeatureExtractor()
+				//				, new TemporalPETExtractor()
+				//, new TemporalPathExtractor()
+				//				, new EventVerbRelationTreeExtractor()
+				, new NumberOfEventTimeBetweenCandidatesExtractor()
+				//				, new SectionHeaderRelationExtractor()
+				, new NearbyVerbTenseRelationExtractor()
+				, new CheckSpecialWordRelationExtractor()
+				, new NearestFlagFeatureExtractor()
+				, new DependencyPathFeaturesExtractor()
+				, new DependencyFeatureExtractor()
+				//				, new SRLRelationFeaturesExtractor()// tried, but not helpful
+				, new EventArgumentPropertyExtractor()
+				, new OverlappedHeadFeaturesExtractor()
+				//				, new EventTimeRelationFeatureExtractor()
+				, new ConjunctionRelationFeaturesExtractor()
+				//				, new EventPositionRelationFeaturesExtractor() //tried, but not helpful
+				, new TimeXRelationFeaturesExtractor()
+				, new TemporalPETFlatExtractor()
+				, new TimeXPropertyRelationFeaturesExtractor()
+				//				, new TimeWordTypeRelationExtractor() //tried, but not helpful
+				//				, new EventIndexOfSameSentenceRelationFeaturesExtractor() //tried, but not helpful
+				);
+	}
+
+	@Override
+	protected Class<? extends Annotation> getCoveringClass() {
+		return Sentence.class;
+	}
+
+	@Override
+	public List<IdentifiedAnnotationPair> getCandidateRelationArgumentPairs(
+			JCas jCas,
+			Annotation sentence) {
+		Map<EventMention, Collection<EventMention>> coveringMap =
+				JCasUtil.indexCovering(jCas, EventMention.class, EventMention.class);
+		
+		List<IdentifiedAnnotationPair> pairs = Lists.newArrayList();
+		for (EventMention event : JCasUtil.selectCovered(jCas, EventMention.class, sentence)) {
+			// ignore subclasses like Procedure and Disease/Disorder
+			if(this.isTraining()){//if training mode, train on both gold event and nearby system events
+				
+				if (event.getClass().equals(EventMention.class)) {
+					for (TimeMention time : JCasUtil.selectCovered(jCas, TimeMention.class, sentence)) {
+						Collection<EventMention> eventList = coveringMap.get(event);
+						for(EventMention covEvent : eventList){
+							pairs.add(new IdentifiedAnnotationPair(covEvent, time));
+						}
+						pairs.add(new IdentifiedAnnotationPair(event, time));
+					}
+				}
+			}else{//if testing mode, only test on system generated events
+				if (event.getClass().equals(EventMention.class)) {
+					for (TimeMention time : JCasUtil.selectCovered(jCas, TimeMention.class, sentence)) {
+						pairs.add(new IdentifiedAnnotationPair(event, time));
+					}
+				}
+			}
+		}
+
+		return pairs;
+	}
+
+	@Override
+	protected void createRelation(JCas jCas, IdentifiedAnnotation arg1,
+			IdentifiedAnnotation arg2, String predictedCategory) {
+		RelationArgument relArg1 = new RelationArgument(jCas);
+		relArg1.setArgument(arg1);
+		relArg1.setRole("Arg1");
+		relArg1.addToIndexes();
+		RelationArgument relArg2 = new RelationArgument(jCas);
+		relArg2.setArgument(arg2);
+		relArg2.setRole("Arg2");
+		relArg2.addToIndexes();
+		TemporalTextRelation relation = new TemporalTextRelation(jCas);
+		relation.setArg1(relArg1);
+		relation.setArg2(relArg2);
+		relation.setCategory(predictedCategory);
+		relation.addToIndexes();
+	}
+
+
+	@Override
+	protected String getRelationCategory(
+			Map<List<Annotation>, BinaryTextRelation> relationLookup,
+			IdentifiedAnnotation arg1,
+			IdentifiedAnnotation arg2) {
+		BinaryTextRelation relation = relationLookup.get(Arrays.asList(arg1, arg2));
+		String category = null;
+		if (relation != null) {
+			category = relation.getCategory();
+		} else {
+			relation = relationLookup.get(Arrays.asList(arg2, arg1));
+			if (relation != null) {
+				if(relation.getCategory().equals("OVERLAP")){
+					category = relation.getCategory();
+					//				}else if (relation.getCategory().equals("BEFORE")){
+					//					category = "AFTER";
+					//				}else if (relation.getCategory().equals("AFTER")){
+					//					category = "BEFORE";
+					//				}
+				}else{
+					category = relation.getCategory() + "-1";
+				}
+			}
+		}
+
+		if(category!=null){
+			if(!((EventMention)arg1).getClass().equals(EventMention.class)){
+				System.out.println("find system-event relations: "+ arg1.getCoveredText() + " -"+category+"- " + arg2.getCoveredText());
+			}else{
+				System.out.println("find gold-event relations: "+ arg1.getCoveredText() + " -"+category+"- " + arg2.getCoveredText());
+			}
+		}
+
+		if (category == null && coin.nextDouble() <= this.probabilityOfKeepingANegativeExample) {
+			category = NO_RELATION_CATEGORY;
+		}
+
+		return category;
+	}
+}

Modified: ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/feature/CheckSpecialWordRelationExtractor.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/feature/CheckSpecialWordRelationExtractor.java?rev=1634983&r1=1634982&r2=1634983&view=diff
==============================================================================
--- ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/feature/CheckSpecialWordRelationExtractor.java (original)
+++ ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/feature/CheckSpecialWordRelationExtractor.java Tue Oct 28 21:01:06 2014
@@ -18,65 +18,152 @@
  */
 package org.apache.ctakes.temporal.ae.feature;
 
+import java.io.IOException;
+import java.net.URL;
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
 import java.util.List;
-import java.util.Map;
 
 import org.apache.ctakes.relationextractor.ae.features.RelationFeaturesExtractor;
-import org.apache.ctakes.typesystem.type.syntax.WordToken;
-import org.apache.ctakes.typesystem.type.textsem.EventMention;
 import org.apache.ctakes.typesystem.type.textsem.IdentifiedAnnotation;
-import org.apache.ctakes.typesystem.type.textspan.Sentence;
 import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
 import org.apache.uima.jcas.JCas;
 import org.cleartk.ml.Feature;
-import org.apache.uima.fit.util.JCasUtil;
+import org.cleartk.timeml.util.TimeWordsExtractor;
+import org.springframework.util.StringUtils;
+
+import com.google.common.base.Charsets;
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Multimap;
+import com.google.common.io.Resources;
 
 public class CheckSpecialWordRelationExtractor implements RelationFeaturesExtractor{
-	
-	final static List<String> specialWd = Arrays.asList("before","prior","previous","previously","ago","soon","earlier","early","after","later","subsequent","follow","following","followed","post","since","back","start","started","by","past","starting");
+
+	//final static List<String> specialWd = Arrays.asList("before","prior","previous","previously","ago","soon","earlier","early","after","later","subsequent","follow","following","followed","post","since","back","start","started","by","past","starting");
+	private static final String LOOKUP_PATH = "/org/apache/ctakes/temporal/TimeLexicon.csv";
+
+	private Multimap<String, String> specialWd;
+
+	public CheckSpecialWordRelationExtractor() {
+		this.specialWd = ArrayListMultimap.create();
+		URL url = TimeWordsExtractor.class.getResource(LOOKUP_PATH);
+		try {
+			for (String line : Resources.readLines(url, Charsets.US_ASCII)) {
+				String[] WordAndType = line.split(",");
+				if (WordAndType.length != 2) {
+					throw new IllegalArgumentException("Expected '<word>,<type>', found: " + line);
+				}
+				this.specialWd.put(WordAndType[0], WordAndType[1]);
+			}
+		} catch (IOException e) {
+			System.err.println("TimeLexicon resource initialization error.");
+		}
+	}
 
 	@Override
 	public List<Feature> extract(JCas jcas, IdentifiedAnnotation arg1,
 			IdentifiedAnnotation arg2) throws AnalysisEngineProcessException {
-		List<Feature> feats = new ArrayList<Feature>();
+		List<Feature> feats = new ArrayList<>();
 
-		//find event
-		EventMention event = null;
-		if(arg1 instanceof EventMention){
-			event = (EventMention) arg1;
-		}else if(arg2 instanceof EventMention){
-			event = (EventMention) arg2;
+		// swap the order if necessary:
+		if(isBefore(arg2,arg1)){
+			IdentifiedAnnotation temp = arg1;
+			arg1 = arg2;
+			arg2 = temp;
+		}else if(isBefore(arg1,arg2)){
+			//keep the order of arg1 arg2
 		}else{
-			return feats;
+			return feats; //don't do anything if arg1 overlap arg2
 		}
 
 		//1 get covering sentence:
-		Map<EventMention, Collection<Sentence>> coveringMap =
-				JCasUtil.indexCovering(jcas, EventMention.class, Sentence.class);
-		Collection<Sentence> sentList = coveringMap.get(event);
-
-		//2 get Verb Tense
-		if (sentList != null && !sentList.isEmpty()){
-			for(Sentence sent : sentList) {
-				for ( WordToken wt : JCasUtil.selectCovered(jcas, WordToken.class, sent)) {
-					if (wt != null){
-						String wdtext = wt.getCoveredText().toLowerCase();
-						if (specialWd.contains(wdtext)){
-							Feature feature = new Feature("SpecialWd", wdtext);
-							feats.add(feature);
-						}
-					}
-				}
-				
-				//logger.info("found nearby verb's pos tag: "+ verbTP);
+//		Map<IdentifiedAnnotation, Collection<Sentence>> coveringMap =
+//				JCasUtil.indexCovering(jcas, IdentifiedAnnotation.class, Sentence.class);
+//
+		int begin = arg1.getEnd();
+		int end = arg2.getBegin();
+//		int window = 30;
+//
+//		//get two covering sentences for arg1 and arg2, two arguments could come from different sentences.
+//		List<Sentence> sentList = new ArrayList<>();
+//		sentList.addAll(coveringMap.get(arg1));
+//		if(sentList.isEmpty()) return feats;
+//		Sentence arg1Sent = sentList.get(0);
+//
+//		sentList = new ArrayList<>();
+//		sentList.addAll(coveringMap.get(arg2));
+//		if(sentList.isEmpty()) return feats;
+//		Sentence arg2Sent = sentList.get(0);
+
+
+		String textInBetween = null;
+		//		String textAfterArg1 = null;
+		//		String textBeforeArg2 = null;
+		//		if(end-begin <= 2* window){
+		textInBetween = jcas.getDocumentText().substring(begin, end).replaceAll("[\r\n]", " ").toLowerCase();
+		//		}else{
+		//			int arg1tail = Math.min(begin + window, arg1Sent.getEnd());
+		//			textAfterArg1 = jcas.getDocumentText().substring(begin, arg1tail).replaceAll("[\r\n]", " ").toLowerCase();
+		//			int arg2head = Math.max(end - window, arg2Sent.getBegin());
+		//			textBeforeArg2 = jcas.getDocumentText().substring(arg2head, end).replaceAll("[\r\n]", " ").toLowerCase();
+		//		}
+//		int arg1head = Math.max(arg1.getBegin()-window, arg1Sent.getBegin());
+//		String textBeforeArg1 = jcas.getDocumentText().substring(arg1head, arg1.getBegin()).replaceAll("[\r\n]", " ").toLowerCase();
+//		int arg2tail = Math.min(arg2.getEnd()+window, arg2Sent.getEnd());
+//		String textAfterArg2 = jcas.getDocumentText().substring(arg2.getEnd(), arg2tail).replaceAll("[\r\n]", " ").toLowerCase();
+		String textInArg1 = jcas.getDocumentText().substring(arg1.getBegin(), arg1.getEnd()).replaceAll("[\r\n]", " ").toLowerCase();
+		String textInArg2 = jcas.getDocumentText().substring(arg2.getBegin(), arg2.getEnd()).replaceAll("[\r\n]", " ").toLowerCase();
+
+		for(String lexicon : specialWd.keySet()){
+			if( textInBetween != null && textInBetween.matches(".*\\b"+lexicon+"\\b.*")){
+				String type = StringUtils.collectionToCommaDelimitedString(specialWd.get(lexicon));
+				Feature feature = new Feature("SpecialWd_InBetween", type);
+				feats.add(feature);
 			}
-
+//			if( textBeforeArg1.matches(".*\\b"+lexicon+"\\b.*")){
+//				String type = StringUtils.collectionToCommaDelimitedString(specialWd.get(lexicon));
+//				Feature feature = new Feature("SpecialWd_BeforeArg1", type);
+//				feats.add(feature);
+//			}
+			if( textInArg1.matches(".*\\b"+lexicon+"\\b.*")){
+				String type = StringUtils.collectionToCommaDelimitedString(specialWd.get(lexicon));
+				Feature feature = new Feature("SpecialWd_InArg1", type);
+				feats.add(feature);
+			}
+			//			if( textAfterArg1 != null && textAfterArg1.matches(".*\\b"+lexicon+"\\b.*")){
+			//				String type = StringUtils.collectionToCommaDelimitedString(specialWd.get(lexicon));
+			//				Feature feature = new Feature("SpecialWd_AfterArg1", type);
+			//				feats.add(feature);
+			//			}
+			//			if( textBeforeArg2 != null && textBeforeArg2.matches(".*\\b"+lexicon+"\\b.*")){
+			//				String type = StringUtils.collectionToCommaDelimitedString(specialWd.get(lexicon));
+			//				Feature feature = new Feature("SpecialWd_BeforeArg2", type);
+			//				feats.add(feature);
+			//			}
+			if( textInArg2.matches(".*\\b"+lexicon+"\\b.*")){
+				String type = StringUtils.collectionToCommaDelimitedString(specialWd.get(lexicon));
+				Feature feature = new Feature("SpecialWd_InArg2", type);
+				feats.add(feature);
+			}
+//			if( textAfterArg2.matches(".*\\b"+lexicon+"\\b.*")){
+//				String type = StringUtils.collectionToCommaDelimitedString(specialWd.get(lexicon));
+//				Feature feature = new Feature("SpecialWd_AfterArg2", type);
+//				feats.add(feature);
+//			}
 		}
+
+		//logger.info("found nearby verb's pos tag: "+ verbTP);
 		return feats;
 	}
 
+	private static boolean isBefore(IdentifiedAnnotation arg1,
+			IdentifiedAnnotation arg2) {
+		if(arg1.getBegin()<arg2.getBegin()){
+			if(arg1.getEnd()<arg2.getBegin()){
+				return true;
+			}
+		}
+		return false;
+	}
+
 
 }

Modified: ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/feature/EventTimeRelationFeatureExtractor.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/feature/EventTimeRelationFeatureExtractor.java?rev=1634983&r1=1634982&r2=1634983&view=diff
==============================================================================
--- ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/feature/EventTimeRelationFeatureExtractor.java (original)
+++ ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/feature/EventTimeRelationFeatureExtractor.java Tue Oct 28 21:01:06 2014
@@ -85,7 +85,7 @@ RelationFeaturesExtractor {
 		TimeMention admissionTime = null;
 		//may need better way to identify Discharge Time other than relative span information:
 		for (TimeMention time : JCasUtil.selectCovered(jCas, TimeMention.class, 15, 30)) {
-			if(time.getTimeClass().equals("DATE")){
+			if(time.getTimeClass() != null && time.getTimeClass().equals("DATE")){
 				admissionTime = time;
 				break;
 			}
@@ -94,7 +94,7 @@ RelationFeaturesExtractor {
 		TimeMention dischargeTime = null;
 		//may need better way to identify Discharge Time other than relative span information:
 		for (TimeMention time : JCasUtil.selectCovered(jCas, TimeMention.class, 40, 60)) {
-			if(time.getTimeClass().equals("DATE")){
+			if(time.getTimeClass() != null && time.getTimeClass().equals("DATE")){
 				dischargeTime = time;
 				break;
 			}

Modified: ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/feature/NumberOfEventsInTheSameSentenceExtractor.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/feature/NumberOfEventsInTheSameSentenceExtractor.java?rev=1634983&r1=1634982&r2=1634983&view=diff
==============================================================================
--- ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/feature/NumberOfEventsInTheSameSentenceExtractor.java (original)
+++ ctakes/trunk/ctakes-temporal/src/main/java/org/apache/ctakes/temporal/ae/feature/NumberOfEventsInTheSameSentenceExtractor.java Tue Oct 28 21:01:06 2014
@@ -72,10 +72,10 @@ RelationFeaturesExtractor {
 			int arg2Index = -1;
 			for(int i=0; i< eventsNum; i++){
 				EventMention currentEvent = events.get(i);
-				if(currentEvent==arg1){
+				if(hasOverlappingSpan(currentEvent,arg1)){
 					arg1Index = i;
 				}
-				if(currentEvent==arg2){
+				if(hasOverlappingSpan(currentEvent,arg2)){
 					arg2Index = i;
 				}
 				if(arg1Index!=-1 && arg2Index!=-1){
@@ -107,4 +107,16 @@ RelationFeaturesExtractor {
 		return feats;
 	}
 
+	private static boolean hasOverlappingSpan(EventMention cevent,
+			IdentifiedAnnotation arg) {
+		if(cevent.getBegin()==arg.getBegin() && arg.getEnd()>=cevent.getEnd()){
+			return true;
+		}else if(arg.getBegin()<=cevent.getBegin() && cevent.getEnd()==arg.getEnd()){
+			return true;
+		}else if(arg.getBegin()<=cevent.getBegin() && arg.getEnd()>=cevent.getEnd()){ //if argument cover current (gold) event mention.
+			return true;
+		}
+		return false;
+	}
+
 }