Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
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.eval;
  
  import java.io.File;
  import java.net.URI;
  import java.util.Arrays;
  import java.util.Deque;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.List;
  import java.util.Map;
  import java.util.Set;
  
  //import org.apache.ctakes.temporal.ae.EventTimeSyntacticAnnotator;
  //import org.apache.ctakes.temporal.ae.EventTimeRelationAnnotator;
  //import org.apache.ctakes.temporal.ae.EventEventRelationAnnotator;
  //import org.apache.ctakes.temporal.eval.Evaluation_ImplBase.WriteI2B2XML;
  //import org.apache.ctakes.temporal.eval.Evaluation_ImplBase.XMLFormat;
  import  org.cleartk.ml.jar.JarClassifierBuilder;
  import  org.cleartk.ml.liblinear.LibLinearStringOutcomeDataWriter;
  //import org.cleartk.ml.libsvm.LIBSVMStringOutcomeDataWriter;
  //import org.cleartk.ml.tksvmlight.TKSVMlightStringOutcomeDataWriter;
  import  org.cleartk.ml.tksvmlight.model.CompositeKernel.ComboOperator;
  import  org.cleartk.eval.AnnotationStatistics;
  import  org.cleartk.util.ViewUriUtil;
  
  
  public class EvaluationOfEventEventThymeRelations extends
  	static interface TempRelOptions extends Evaluation_ImplBase.Options{
  		@Option
  		public boolean getPrintFormattedRelations();
  
  		@Option
  		public boolean getBaseline();
  
 		public boolean getClosure();
 
 		public boolean getUseTmp();
 
 		public boolean getUseGoldAttributes();
 
 		public boolean getSkipTrain();
 	}
 
 	//  protected static boolean DEFAULT_BOTH_DIRECTIONS = false;
 	//  protected static float DEFAULT_DOWNSAMPLE = 1.0f;
 	//  private static double DEFAULT_SVM_C = 1.0;
 	//  private static double DEFAULT_SVM_G = 1.0;
 	//  private static double DEFAULT_TK = 0.5;
 	//  private static double DEFAULT_LAMBDA = 0.5;
 
 	//  defaultParams = new ParameterSettings(DEFAULT_BOTH_DIRECTIONS, DEFAULT_DOWNSAMPLE, "tk",
 	//  		  DEFAULT_SVM_C, DEFAULT_SVM_G, "polynomial", ComboOperator.SUM, DEFAULT_TK, DEFAULT_LAMBDA);
 			10.0, 1.0, "linear", ComboOperator.VECTOR_ONLY, );
 			100.0, 0.1, "radial basis function", ComboOperator.SUM, 0.5, 0.5);
 			10.0, 1.0, "polynomial", ComboOperator.SUM, 0.1, 0.5);  // (0.3, 0.4 for tklibsvm)
 			1.0, 0.1, "radial basis function", ComboOperator.SUM, 0.5, 0.5);
 	private static Boolean recallModeEvaluation = true;
 	
 	static int sysRelationCount;
 	static int closeRelationCount;
 	static int goldRelationCount;
 	static int closeGoldRelationCount;
 
 	public static void main(String[] argsthrows Exception {
 		
 		TempRelOptions options = CliFactory.parseArguments(TempRelOptions.classargs);
 		List<IntegertrainItems = null;
 		List<IntegerdevItems = null;
 		List<IntegertestItems = null;
 
 		List<IntegerpatientSets = options.getPatients().getList();
 		if(options.getXMLFormat() == .){
 			trainItems = I2B2Data.getTrainPatientSets(options.getXMLDirectory());
 			devItems = I2B2Data.getDevPatientSets(options.getXMLDirectory());
 			testItems = I2B2Data.getTestPatientSets(options.getXMLDirectory());
 		}else{
 			trainItems = THYMEData.getPatientSets(patientSetsoptions.getTrainRemainders().getList());
 			devItems = THYMEData.getPatientSets(patientSetsoptions.getDevRemainders().getList());
 			testItems = THYMEData.getPatientSets(patientSetsoptions.getTestRemainders().getList());
 		}
 
 		//    possibleParams.add(defaultParams);
 
 		//    for(ParameterSettings params : possibleParams){
 		try{
 			File workingDir = new File("target/eval/thyme/");
 			if(!workingDir.exists()) workingDir.mkdirs();
 			if(options.getUseTmp()){
 				File tempModelDir = File.createTempFile("temporal"nullworkingDir);
 				tempModelDir.delete();
 				tempModelDir.mkdir();
 				workingDir = tempModelDir;
 			}
 					workingDir,
 					options.getXMLDirectory(),
 					options.getXMLFormat(),
 					options.getSubcorpus(),
 					options.getXMIDirectory(),
 					options.getClosure(),
 					options.getPrintErrors(),
 					options.getBaseline(),
 					options.getKernelParams(),
 					params);
 //			evaluation.prepareXMIsFor(patientSets);
 			if(options.getI2B2Output()!=nullevaluation.setI2B2Output(options.getI2B2Output() + "/temporal-relations/event-event");
 			List<Integertraining = trainItems;
 			List<Integertesting = null;
 			if(options.getTest()){
 				training.addAll(devItems);
 				testing = testItems;
 			}else{
 				testing = devItems;
 			}
 			
 			evaluation.printErrors = false;
 			
 			//do closure on system, but not on gold, to calculate recall
 			evaluation.skipTrain = options.getSkipTrain();
 			if(evaluation.skipTrain && options.getTest()){
 				evaluation.prepareXMIsFor(testing);
 			}else{
 				evaluation.prepareXMIsFor(patientSets);
 			}
 			evaluation.printErrors=true;
 			params.stats = evaluation.trainAndTest(trainingtesting);//training);//
 			//      System.err.println(options.getKernelParams() == null ? params : options.getKernelParams());
 //			System.err.println("No closure on gold::Closure on System::Recall Mode");
 			..println(params.stats);
 			
 			..println("System predict relations #: ");
 			..println("# of system relations whose arguments are close: ");
 			..println("Gold relations #: ");
 			..println("# of gold relations whose arguments are close: ");
 
 			//do closure on gold, but not on system, to calculate precision
 //			evaluation.skipTrain = true;
 //			recallModeEvaluation = false;
 //			params.stats = evaluation.trainAndTest(training, testing);//training);//
 //			//      System.err.println(options.getKernelParams() == null ? params : options.getKernelParams());
 //			System.err.println("No closure on System::Closure on Gold::Precision Mode");
 //			System.err.println(params.stats);
 //
 //			//do closure on train, but not on test, to calculate plain results
 //			evaluation.skipTrain = true;
 //			evaluation.useClosure = false;
 //			params.stats = evaluation.trainAndTest(training, testing);//training);//
 //			//      System.err.println(options.getKernelParams() == null ? params : options.getKernelParams());
 //			System.err.println("Closure on train::No closure on Test::Plain Mode");
 //			System.err.println(params.stats);
 
 			if(options.getUseTmp()){
 				// won't work because it's not empty. should we be concerned with this or is it responsibility of 
 				// person invoking the tmp flag?
 				FileUtils.deleteRecursive(workingDir);
 			}
 			..println("Error with parameter settings: " + params);
 		}
 	}
 
 	//  private ParameterSettings params;
 	private boolean baseline;
 	protected boolean useClosure;
 	protected boolean useGoldAttributes;
 	protected boolean skipTrain=false;
 	//  protected boolean printRelations = false;
 
 			File baseDirectory,
 			File rawTextDirectory,
 			File xmlDirectory,
 			XMLFormat xmlFormat,
 			Subcorpus subcorpus,
 			File xmiDirectory,
 			File treebankDirectory,
 			boolean useClosure,
 			boolean printErrors,
 			boolean printRelations,
 			boolean baseline,
 			boolean useGoldAttributes,
 			String kernelParams,
 		super(
 				baseDirectory,
 				rawTextDirectory,
 				xmlDirectory,
 				xmlFormat,
 				subcorpus,
 				xmiDirectory,
 				treebankDirectory,
 				printErrors,
 				printRelations,
 				params);
 		this. = params;
 		this. = useClosure;
 		this. = printErrors;
 		this. = printRelations;
 		this. = useGoldAttributes;
 		this. = baseline;
 		this. = kernelParams == null ? null : kernelParams.split(" ");
 	}
 
 	//  public EvaluationOfTemporalRelations(File baseDirectory, File rawTextDirectory,
 	//      File knowtatorXMLDirectory, File xmiDirectory) {
 	//
 	//    super(baseDirectory, rawTextDirectory, knowtatorXMLDirectory, xmiDirectory, null);
 	//    this.params = defaultParams;
 	//    this.printErrors = false;
 	//  }
 
 	protected void train(CollectionReader collectionReaderFile directorythrows Exception {
 		//	  if(this.baseline) return;
 		if(this.return;
 		AggregateBuilder aggregateBuilder = this.getPreprocessorAggregateBuilder();
 		aggregateBuilder.add(CopyFromGold.getDescription(EventMention.classTimeMention.classBinaryTextRelation.class));
 		aggregateBuilder.add(AnalysisEngineFactory.createEngineDescription(RemoveCrossSentenceRelations.class));
 		if(!this.){
 			aggregateBuilder.add(AnalysisEngineFactory.createEngineDescription(RemoveGoldAttributes.class));
 		}
 		
 		aggregateBuilder.add(AnalysisEngineFactory.createEngineDescription(PreserveEventEventRelations.class));
 		
 		if (this.) {
 			aggregateBuilder.add(AnalysisEngineFactory.createEngineDescription(AddClosure.class));//aggregateBuilder.add(AnalysisEngineFactory.createPrimitiveDescription(AddTransitiveContainsRelations.class));
 			//			aggregateBuilder.add(AnalysisEngineFactory.createPrimitiveDescription(AddContain2Overlap.class));
 			//			aggregateBuilder.add(AnalysisEngineFactory.createPrimitiveDescription(AddTransitiveBeforeAndOnRelations.class));
 		}
 		aggregateBuilder.add(AnalysisEngineFactory.createEngineDescription(RemoveNonContainsRelations.class));
 		//		aggregateBuilder.add(AnalysisEngineFactory.createPrimitiveDescription(AddFlippedOverlap.class));//add flipped overlap instances to training data
 
 		aggregateBuilder.add(AnalysisEngineFactory.createEngineDescription(Overlap2Contains.class));
 		
 		
 		//		aggregateBuilder.add(AnalysisEngineFactory.createPrimitiveDescription(RemoveNonUMLSEvents.class));
 		
 		//add unlabeled nearby system events as potential links: 
 		aggregateBuilder.add(AnalysisEngineFactory.createEngineDescription(AddEEPotentialRelations.class));
 				
 		aggregateBuilder.add(EventEventRelationAnnotator.createDataWriterDescription(
 				LibLinearStringOutcomeDataWriter.class,
 				//				LIBSVMStringOutcomeDataWriter.class,
 				//				TKSVMlightStringOutcomeDataWriter.class,
 				//        TKLIBSVMStringOutcomeDataWriter.class,
 				//        SVMlightStringOutcomeDataWriter.class,        
 				new File(directory,"event-event"),
 		//		aggregateBuilder.add(EventEventRelationAnnotator.createDataWriterDescription(
 		//				LIBSVMStringOutcomeDataWriter.class,
 		//				new File(directory,"event-event"), 
 		//				params.probabilityOfKeepingANegativeExample));
 		SimplePipeline.runPipeline(collectionReaderaggregateBuilder.createAggregate());
 		String[] optArray;
 
 		if(this. == null){
 			ArrayList<StringsvmOptions = new ArrayList<>();
 			svmOptions.add("-c"); svmOptions.add(""+.);        // svm cost
 			svmOptions.add("-t"); svmOptions.add(""+.); // kernel index 
 			svmOptions.add("-d"); svmOptions.add("3");                      // degree parameter for polynomial
 			svmOptions.add("-g"); svmOptions.add(""+.);
 				svmOptions.add("-S"); svmOptions.add(""+.);   // second kernel index (similar to -t) for composite kernel
 				String comboFlag = (. == ComboOperator.SUM ? "+" : . == ComboOperator.PRODUCT ? "*" : . == ComboOperator.TREE_ONLY ? "T" : "V");
 				svmOptions.add("-C"); svmOptions.add(comboFlag);
 				svmOptions.add("-L"); svmOptions.add(""+.);
 				svmOptions.add("-T"); svmOptions.add(""+.);
 				svmOptions.add("-N"); svmOptions.add("3");   // normalize trees and features
 			}
 			optArray = svmOptions.toArray(new String[]{});
 		}else{
 			optArray = this.;
 			for(int i = 0; i < optArray.lengthi+=2){
 				optArray[i] = "-" + optArray[i];
 			}
 		}
 
 		//    HideOutput hider = new HideOutput();
 		JarClassifierBuilder.trainAndPackage(new File(directory,"event-event"),"-w2","13","-w3","86","-c"optArray[1]);//"-w2","12","-w3","102",//"-w1","29","-w3","12","-w4","80","-w5","228","-w6","79","-w7","49","-w8","157","-w9","553","-w10","384",//"-w1","29","-w3","12","-w4","79","-w5","255","-w6","75","-w7","50","-w8","144","-w9","544","-w10","384",//"-w1","25","-w3","9","-w4","79","-w5","267","-w6","89","-w7","60","-w8","152","-w9","615","-w10","404",//"-w1","0.2","-w3","15","-w4","4","-w5","64","-w6","24","-w7","29","-w9","70","-c", optArray[1]);"-c", "0.05");//"0.08","-w3","3","-w4","17","-w5","20","-w6","16","-w7","10","-w8","6", "-w9","45","-w10","30","-c", optArray[1]);//"-c", "0.05");//optArray);
 		//		JarClassifierBuilder.trainAndPackage(new File(directory,"event-event"), "-h","0","-c", "1000");
 		//    hider.restoreOutput();
 		//    hider.close();
 	}
 
 	protected AnnotationStatistics<Stringtest(CollectionReader collectionReaderFile directory)
 			throws Exception {
 		this.=false;
 		AggregateBuilder aggregateBuilder = this.getPreprocessorAggregateBuilder();
 		aggregateBuilder.add(CopyFromGold.getDescription(EventMention.classTimeMention.class));
 
 		aggregateBuilder.add(AnalysisEngineFactory.createEngineDescription(
 		
 		aggregateBuilder.add(
 
 		if (! && this.) { //closure for gold
 			aggregateBuilder.add(
 					AnalysisEngineFactory.createEngineDescription(AddClosure.class),//AnalysisEngineFactory.createPrimitiveDescription(AddTransitiveContainsRelations.class),
 		}
 		
 		aggregateBuilder.add(AnalysisEngineFactory.createEngineDescription(RemoveNonContainsRelations.class),
 		
 //		aggregateBuilder.add(AnalysisEngineFactory.createEngineDescription(RemoveNonUMLSEvents.class));
 
 		aggregateBuilder.add(AnalysisEngineFactory.createEngineDescription(RemoveRelations.class));
 		aggregateBuilder.add(this. ? RecallBaselineEventTimeRelationAnnotator.createAnnotatorDescription(directory) :
 			EventEventRelationAnnotator.createAnnotatorDescription(new File(directory,"event-event")));
 		
 		//count how many system predicted relations, their arguments are close to each other, without any other event in between
 		aggregateBuilder.add(AnalysisEngineFactory.createEngineDescription(CountCloseRelation.class));
 
 		if(this. != null){
 			aggregateBuilder.add(AnalysisEngineFactory.createEngineDescription(WriteI2B2XML.class.this.), "TimexView".);
 		}
 
 		File outf = null;
 		if ( && this.) {//add closure for system output
 			aggregateBuilder.add(
 					AnalysisEngineFactory.createEngineDescription(AddClosure.class),//AnalysisEngineFactory.createPrimitiveDescription(AddTransitiveContainsRelations.class),
 					);
 			outf =  new File("target/eval/thyme/SystemError_eventEvent_recall_test.txt");
 		}else if (! && this.){
 			outf =  new File("target/eval/thyme/SystemError_eventEvent_precision_test.txt");
 		}else{
 			outf =  new File("target/eval/thyme/SystemError_eventEvent_plain_test.txt");
 		}
 
 		PrintWriter outDrop =null;
 		outDrop = new PrintWriter(new BufferedWriter(new FileWriter(outffalse)));
 
 				return new HashableArguments(relation);
 			}
 		};
 		Function<BinaryTextRelationStringgetOutcome = AnnotationStatistics.annotationToFeatureValue("category");
 
 		AnnotationStatistics<Stringstats = new AnnotationStatistics<>();
 		JCasIterator jcasIter =new JCasIterator(collectionReaderaggregateBuilder.createAggregate());
 		JCas jCas = null;
 		while(jcasIter.hasNext()) {
 			jCas = jcasIter.next();
 			JCas goldView = jCas.getView();
 			JCas systemView = jCas.getView(.);
 			Collection<BinaryTextRelationgoldRelations = JCasUtil.select(
 					goldView,
 			Collection<BinaryTextRelationsystemRelations = JCasUtil.select(
 					systemView,
 
 			//newly add
 			//			systemRelations = removeNonGoldRelations(systemRelations, goldRelations, getSpan);//for removing non-gold pairs
 			//			systemRelations = correctArgOrder(systemRelations, goldRelations);//change the argument order of "OVERLAP" relation, if the order is flipped
 			//find duplicates in gold relations:
 			//			Collection<BinaryTextRelation> duplicateGoldRelations = getDuplicateRelations(goldRelations, getSpan);
 			//			if(!duplicateGoldRelations.isEmpty()){
 			//				System.err.println("******Duplicate gold relations in : " + ViewURIUtil.getURI(jCas).toString());
 			//				for (BinaryTextRelation rel : duplicateGoldRelations){
 			//					System.err.println("Duplicate : "+ formatRelation(rel));
 			//				}
 			//			}
 			//end newly add
 
 			stats.add(goldRelationssystemRelationsgetSpangetOutcome);
 			if(this.){
 				URI uri = ViewUriUtil.getURI(jCas);
 				String[] path = uri.getPath().split("/");
 				printRelationAnnotations(path[path.length - 1], systemRelations);
 			}
 			if(this.){
 				for (BinaryTextRelation relation : goldRelations) {
 					goldMap.put(new HashableArguments(relation), relation);
 				}
 				for (BinaryTextRelation relation : systemRelations) {
 					systemMap.put(new HashableArguments(relation), relation);
 				}
 				Set<HashableArgumentsall = Sets.union(goldMap.keySet(), systemMap.keySet());
 				List<HashableArgumentssorted = Lists.newArrayList(all);
 				Collections.sort(sorted);
 				outDrop.println("Doc id: " + ViewUriUtil.getURI(jCas).toString());
 				for (HashableArguments key : sorted) {
 					BinaryTextRelation goldRelation = goldMap.get(key);
 					BinaryTextRelation systemRelation = systemMap.get(key);
 					if (goldRelation == null) {
 						outDrop.println("System added: " + formatRelation(systemRelation));
 					} else if (systemRelation == null) {
 						outDrop.println("System dropped: " + formatRelation(goldRelation));
 					} else if (!systemRelation.getCategory().equals(goldRelation.getCategory())) {
 						String label = systemRelation.getCategory();
 						outDrop.printf("System labeled %s for %s\n"labelformatRelation(goldRelation));
 					} else{
 						outDrop.println("Nailed it! " + formatRelation(systemRelation));
 					}
 				}
 			}
 		}
 		outDrop.close();
 		return stats;
 	}
 	
 	public static class CountCloseRelation extends JCasAnnotator_ImplBase {
 
 		
 		public void process(JCas jCasthrows AnalysisEngineProcessException {
 			JCas systemViewgoldView;
 			int sizeLimit = 6;
 			try {
 				systemView = jCas.getView(this.);
 				goldView = jCas.getView();
 			} catch (CASException e) {
 			}
 
 			//count how many sentences have timex, and how many sentences have only one timex
 			for (TemporalTextRelation relation : JCasUtil.select(systemViewTemporalTextRelation.class)) {
 				Annotation arg1 = relation.getArg1().getArgument();
 				Annotation arg2 = relation.getArg2().getArgument();
 				ifarg1.getBegin()> arg2.getBegin()){
 					Annotation temp = arg1;
 					arg1 = arg2;
 					arg2 = temp;
 				}
 				List<WordTokenwords = JCasUtil.selectBetween(systemViewWordToken.classarg1arg2);
 				if(words.size()<sizeLimit){
 				}
 			}
 			
 			Map<List<Annotation>, TemporalTextRelationrelationLookup = new HashMap<>();
 			for (TemporalTextRelation relation : Lists.newArrayList(JCasUtil.select(goldViewTemporalTextRelation.class))) {
 				Annotation arg1 = relation.getArg1().getArgument();
 				Annotation arg2 = relation.getArg2().getArgument();
 				// The key is a list of args so we can do bi-directional lookup
 				List<Annotationkey = Arrays.asList(arg1arg2);
 				if(!relationLookup.containsKey(key)){
 					relationLookup.put(keyrelation);
 				}
 			}
 
 			//count how many sentences have timex, and how many sentences have only one timex
 			for (TemporalTextRelation relation : relationLookup.values()) {
 				Annotation arg1 = relation.getArg1().getArgument();
 				Annotation arg2 = relation.getArg2().getArgument();
 				ifarg1.getBegin()> arg2.getBegin()){
 					Annotation temp = arg1;
 					arg1 = arg2;
 					arg2 = temp;
 				}
 				List<WordTokenwords = JCasUtil.selectBetween(systemViewWordToken.classarg1arg2);
 				if(words.size()<sizeLimit){
 				}
 			}
 		}
 	}
 
 		public static final String PARAM_GOLD_VIEW = "GoldView";
 
 		@ConfigurationParameter(name = ,mandatory=false)
 
 		public void process(JCas jCasthrows AnalysisEngineProcessException {
 			JCas sysView;
 			JCas goldView;
 			try {
 				sysView = jCas.getView(.);
 				goldView = jCas.getView();
 			} catch (CASException e) {
 			}
 			for(TemporalTextRelation relation : Lists.newArrayList(JCasUtil.select(goldViewTemporalTextRelation.class))){
 				Annotation arg1 = relation.getArg1().getArgument();
 				Annotation arg2 = relation.getArg2().getArgument();
 				boolean arg1Valid = false;
 				boolean arg2Valid = false;
 				for (EventMention event : JCasUtil.selectCovered(sysViewEventMention.classarg1)){
 					if(!event.getClass().equals(EventMention.class)){
 						arg1Valid = true;
 						break;
 					}
 				}
 				for (EventMention event : JCasUtil.selectCovered(sysViewEventMention.classarg2)){
 					if(!event.getClass().equals(EventMention.class)){
 						arg2Valid = true;
 						break;
 					}
 				}
 				if(arg1Valid && arg2Valid){
 					// these are the kind we keep.
 					continue;
 				}
 				relation.removeFromIndexes();
 			}
 		}   
 	}
 	
 		public static final String PARAM_RELATION_VIEW = "RelationView";
 		@ConfigurationParameter(name = ,mandatory=false)
 
 		public void process(JCas jCasthrows AnalysisEngineProcessException {
 			JCas relationView;
 			try {
 				relationView = jCas.getView(this.);
 			} catch (CASException e) {
 			}
 
 			Set<List<EventMention>> relationLookup = new HashSet<>();
 			
 					  JCasUtil.indexCovering(relationViewEventMention.classEventMention.class);
 			for(TemporalTextRelation relation : Lists.newArrayList(JCasUtil.select(relationViewTemporalTextRelation.class))){
 				Annotation arg1 = relation.getArg1().getArgument();
 				Annotation arg2 = relation.getArg2().getArgument();
 				if(arg1 instanceof EventMention && arg2 instanceof EventMention){
 					EventMention event1 = (EventMentionarg1;
 					EventMention event2 = (EventMentionarg2;
 					for(EventMention covEventA : coveringMap.get(event1)){
 						List<EventMentionkey = Arrays.asList(covEventAevent2);
 						if(!relationLookup.contains(key) && !hasOverlap(covEventA,event2)){
 							relationLookup.add(key);
 							createRelation(relationViewcovEventAevent2relation.getCategory());
 						}
 						for(EventMention covEventB : coveringMap.get(event2)){
 							key = Arrays.asList(covEventAcovEventB);
 							if(!relationLookup.contains(key) && !hasOverlap(covEventA,covEventB)){
 								relationLookup.add(key);
 								createRelation(relationViewcovEventAcovEventBrelation.getCategory());
 							}
 						}
 					}
 					for(EventMention covEventB : coveringMap.get(event2)){
 						List<EventMentionkey = Arrays.asList(event1covEventB);
 						if(!relationLookup.contains(key) && !hasOverlap(event1,covEventB)){
 							relationLookup.add(key);
 							createRelation(relationViewevent1covEventBrelation.getCategory());
 						}
 					}
 				}
 			}
 
 		}
 
 
 		private static boolean hasOverlap(Annotation event1Annotation event2) {
 			if(event1.getEnd()>=event2.getBegin()&&event1.getEnd()<=event2.getEnd()){
 				return true;
 			}
 			if(event2.getEnd()>=event1.getBegin()&&event2.getEnd()<=event1.getEnd()){
 				return true;
 			}
 			return false;
 		}
 
 		private static void createRelation(JCas jCasAnnotation arg1,
 				Annotation arg2String category) {
 			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(category);
 			relation.addToIndexes();
 			
 		}
 	}
 
 	/*
   private static String formatRelation(BinaryTextRelation relation) {
 	  IdentifiedAnnotation arg1 = (IdentifiedAnnotation)relation.getArg1().getArgument();
 	  IdentifiedAnnotation arg2 = (IdentifiedAnnotation)relation.getArg2().getArgument();
 	  String text = arg1.getCAS().getDocumentText();
 	  int begin = Math.min(arg1.getBegin(), arg2.getBegin());
 	  int end = Math.max(arg1.getBegin(), arg2.getBegin());
 	  begin = Math.max(0, begin - 50);
 	  end = Math.min(text.length(), end + 50);
 	  return String.format(
 			  "%s(%s(type=%d), %s(type=%d)) in ...%s...",
 			  relation.getCategory(),
 			  arg1.getCoveredText(),
 			  arg1.getTypeID(),
 			  arg2.getCoveredText(),
 			  arg2.getTypeID(),
 			  text.substring(begin, end).replaceAll("[\r\n]", " "));
   }
 
   private static void printRelationAnnotations(String fileName, Collection<BinaryTextRelation> relations) {
 
 	  for(BinaryTextRelation binaryTextRelation : relations) {
 
 		  Annotation arg1 = binaryTextRelation.getArg1().getArgument();
 		  Annotation arg2 = binaryTextRelation.getArg2().getArgument();
 
 		  String arg1Type = arg1.getClass().getSimpleName();
 		  String arg2Type = arg2.getClass().getSimpleName();
 
 		  int arg1Begin = arg1.getBegin();
 		  int arg1End = arg1.getEnd();
 		  int arg2Begin = arg2.getBegin();
 		  int arg2End = arg2.getEnd();
 
 		  String category = binaryTextRelation.getCategory();
 
 		  System.out.format("%s\t%s\t%s\t%d\t%d\t%s\t%d\t%d\n", 
 				  fileName, category, arg1Type, arg1Begin, arg1End, arg2Type, arg2Begin, arg2End);
 	  }
   }
 	 */
 
 	
 
 	//	@SuppressWarnings("unchecked")
 	//	private static <SPAN> Collection<BinaryTextRelation> getDuplicateRelations(
 	//			Collection<BinaryTextRelation> goldRelations,
 	//			Function<BinaryTextRelation, ?> getSpan) {
 	//		Set<BinaryTextRelation> duplicateRelations = Sets.newHashSet();
 	//		//build a multimap that map gold span to gold relation
 	//		Multimap<SPAN, BinaryTextRelation> spanToRelation = HashMultimap.create();
 	//		for (BinaryTextRelation relation : goldRelations) {
 	//			spanToRelation.put((SPAN) getSpan.apply(relation), relation);			
 	//		}
 	//		for (SPAN span: spanToRelation.keySet()){
 	//			Collection<BinaryTextRelation> relations = spanToRelation.get(span);
 	//			if(relations.size()>1){//if same span maps to multiple relations
 	//				duplicateRelations.addAll(relations);
 	//			}
 	//		}
 	//		return duplicateRelations;
 	//	}
 
 	//	private static Collection<BinaryTextRelation> removeNonGoldRelations(
 	//			Collection<BinaryTextRelation> systemRelations, Collection<BinaryTextRelation> goldRelations) {
 	//		//remove non-gold pairs from system relations:
 	//		Set<BinaryTextRelation> goodSys = Sets.newHashSet();
 	//
 	//		for(BinaryTextRelation sysrel : systemRelations){
 	//			Annotation sysArg1 = sysrel.getArg1().getArgument();
 	//			Annotation sysArg2 = sysrel.getArg2().getArgument();
 	//			for(BinaryTextRelation goldrel : goldRelations){
 	//				Annotation goldArg1 = goldrel.getArg1().getArgument();
 	//				Annotation goldArg2 = goldrel.getArg2().getArgument();
 	//				if(matchSpan(sysArg1, goldArg1) && matchSpan(sysArg2, goldArg2)){
 	//					goodSys.add(sysrel);
 	//					continue;
 	//				}else if (matchSpan(sysArg2, goldArg1) && matchSpan(sysArg1, goldArg2)){//the order of system pair was flipped 
 	//					if(sysrel.getCategory().equals("OVERLAP")){ //if the relation is overlap, and the arg order was flipped, then change back the order
 	//						RelationArgument tempArg = (RelationArgument) sysrel.getArg1().clone();
 	//						sysrel.setArg1((RelationArgument) sysrel.getArg2().clone());
 	//						sysrel.setArg2(tempArg);
 	//					}//for other types of relation, still maintain the type.
 	//					goodSys.add(sysrel);
 	//					continue;
 	//				}
 	//			}
 	//		}
 	//
 	//		return goodSys;
 	//	}
 
 
 
 
 	/*  public static class RemoveNonTLINKRelations extends JCasAnnotator_ImplBase {
     @Override
     public void process(JCas jCas) throws AnalysisEngineProcessException {
       for (BinaryTextRelation relation : Lists.newArrayList(JCasUtil.select(
           jCas,
           BinaryTextRelation.class))) {
         if (!(relation instanceof TemporalTextRelation)) {
           relation.getArg1().removeFromIndexes();
           relation.getArg2().removeFromIndexes();
           relation.removeFromIndexes();
         }
       }
     }
   }*/
 
 
 		public static final String PARAM_SENTENCE_VIEW = "SentenceView";
 
 		@ConfigurationParameter(name = ,mandatory=false)
 
 		public static final String PARAM_RELATION_VIEW = "RelationView";
 
 		@ConfigurationParameter(name = ,mandatory=false)
 
 		public void process(JCas jCasthrows AnalysisEngineProcessException {
 			JCas sentenceViewrelationView;
 			try {
 				sentenceView = jCas.getView(this.);
 				relationView = jCas.getView(this.);
 			} catch (CASException e) {
 			}
 
 			// map events and times to the sentences that contain them
 			Map<IdentifiedAnnotationIntegersentenceIndex = Maps.newHashMap();
 			int index = -1;
 			for (Sentence sentence : JCasUtil.select(sentenceViewSentence.class)) {
 				++index;
 				for (EventMention event : JCasUtil.selectCovered(relationViewEventMention.classsentence)) {
 					sentenceIndex.put(eventindex);
 				}
 				for (TimeMention time : JCasUtil.selectCovered(relationViewTimeMention.classsentence)) {
 					sentenceIndex.put(timeindex);
 				}
 			}
 
 			// remove any relations that are in different sentences.
 			for (BinaryTextRelation relation : Lists.newArrayList(JCasUtil.select(
 					relationView,
 					BinaryTextRelation.class))) {
 				Integer sent1 = sentenceIndex.get(relation.getArg1().getArgument());
 				Integer sent2 = sentenceIndex.get(relation.getArg2().getArgument());
 				if (sent1 == null || sent2 == null || !sent1.equals(sent2)) {
 					relation.getArg1().removeFromIndexes();
 					relation.getArg2().removeFromIndexes();
 					relation.removeFromIndexes();
 				}
 			}
 		}
 	}
 
 
 	public static class RemoveRelations extends org.apache.uima.fit.component.JCasAnnotator_ImplBase {
 		public void process(JCas jCasthrows AnalysisEngineProcessException {
 			for (BinaryTextRelation relation : Lists.newArrayList(JCasUtil.select(
 					jCas,
 					BinaryTextRelation.class))) {
 				relation.getArg1().removeFromIndexes();
 				relation.getArg2().removeFromIndexes();
 				relation.removeFromIndexes();
 			}
 		}
 	}
 
 
 
 		public void process(JCas jCasthrows AnalysisEngineProcessException {
 
 			// collect many-to-many mappings of containment relations 
 			Multimap<AnnotationAnnotationisContainedIn = HashMultimap.create();
 			Multimap<AnnotationAnnotationcontains = HashMultimap.create();
 			Set<BinaryTextRelationcontainsRelations = Sets.newHashSet();
 			for (BinaryTextRelation relation : JCasUtil.select(jCasBinaryTextRelation.class)) {
 				if (relation.getCategory().equals("CONTAINS")) {
 					containsRelations.add(relation);
 					Annotation arg1 = relation.getArg1().getArgument();
 					Annotation arg2 = relation.getArg2().getArgument();
 					contains.put(arg1arg2);
 					isContainedIn.put(arg2arg1);
 				}
 			}
 
 			// look for X -> Y -> Z containment chains and add X -> Z relations
 			Deque<Annotationtodo = new ArrayDeque<>(isContainedIn.keySet());
 			while (!todo.isEmpty()) {
 				Annotation next = todo.removeFirst();
 				for (Annotation parent : Lists.newArrayList(isContainedIn.get(next))) {
 					for (Annotation grandParent : Lists.newArrayList(isContainedIn.get(parent))) {
 						if (!isContainedIn.containsEntry(nextgrandParent)) {
 							isContainedIn.put(nextgrandParent);
 							contains.put(grandParentnext);
 
 							// once X -> Z has been added, we need to re-do all W where W -> X
 							for (Annotation child : contains.get(next)) {
 								todo.add(child);
 							}
 						}
 					}
 				}
 			}
 
 			// remove old relations
 			for (BinaryTextRelation relation : containsRelations) {
 				relation.getArg1().removeFromIndexes();
 				relation.getArg2().removeFromIndexes();
 				relation.removeFromIndexes();
 			}
 
 			// add new, transitive relations
 			for (Annotation contained : isContainedIn.keySet()) {
 				for (Annotation container : isContainedIn.get(contained)) {
 					RelationArgument arg1 = new RelationArgument(jCas);
 					arg1.setArgument(container);
 					RelationArgument arg2 = new RelationArgument(jCas);
 					arg2.setArgument(contained);
 					BinaryTextRelation relation = new BinaryTextRelation(jCas);
 					relation.setArg1(arg1);
 					relation.setArg2(arg2);
 					relation.setCategory("CONTAINS");
 					arg1.addToIndexes();
 					arg2.addToIndexes();
 					relation.addToIndexes();
 				}
 			}
 		}
 
 	}
 
 
 		public void process(JCas jCasthrows AnalysisEngineProcessException {
 
 			Set<BinaryTextRelationcontainsRelations = Sets.newHashSet();
 			for (BinaryTextRelation relation : JCasUtil.select(jCasBinaryTextRelation.class)) {
 				if (relation.getCategory().equals("CONTAINS")) {
 					containsRelations.add(relation);
 				}
 			}
 
 			for (BinaryTextRelation relation : containsRelations) {
 				RelationArgument arg1 = (RelationArgumentrelation.getArg1().clone();
 				RelationArgument arg2 = (RelationArgumentrelation.getArg2().clone();
 				BinaryTextRelation newrelation = new BinaryTextRelation(jCas);
 				newrelation.setArg1(arg1);
 				newrelation.setArg2(arg2);
 				newrelation.setCategory("OVERLAP");
 				arg1.addToIndexes();
 				arg2.addToIndexes();
 				newrelation.addToIndexes();
 			}
 		}
 	}
 
 	public static class AddFlippedOverlap extends org.apache.uima.fit.component.JCasAnnotator_ImplBase {
 
 		public void process(JCas jCasthrows AnalysisEngineProcessException {
 
 			Set<BinaryTextRelationoverlapRelations = Sets.newHashSet();
 			Multimap<AnnotationAnnotationoverlaps = HashMultimap.create();
 			for (BinaryTextRelation relation : JCasUtil.select(jCasBinaryTextRelation.class)) {
 				if (relation.getCategory().equals("OVERLAP")) {
 					overlapRelations.add(relation);
 					Annotation arg1 = relation.getArg1().getArgument();
 					Annotation arg2 = relation.getArg2().getArgument();
 					overlaps.put(arg1arg2);
 				}
 			}
 
 			for (BinaryTextRelation orelation : overlapRelations) {
 				Annotation argA = orelation.getArg1().getArgument();
 				Annotation argB = orelation.getArg2().getArgument();
 				//add overlap 
 				if (!overlaps.containsEntry(argBargA)) {
 					//create a new flipped relation:
 					RelationArgument arg1 = new RelationArgument(jCas);
 					arg1.setArgument(argB);
 					RelationArgument arg2 = new RelationArgument(jCas);
 					arg2.setArgument(argA);
 					BinaryTextRelation relation = new BinaryTextRelation(jCas);
 					relation.setArg1(arg1);
 					relation.setArg2(arg2);
 					relation.setCategory("OVERLAP");
 					arg1.addToIndexes();
 					arg2.addToIndexes();
 					relation.addToIndexes();
 					overlaps.put(argBargA);
 				}
 
 			}
 		}
 	}
 
 	public static class AddClosure extends JCasAnnotator_ImplBase {
 
 		public void process(JCas jCasthrows AnalysisEngineProcessException {
 
 			Multimap<List<Annotation>, BinaryTextRelationannotationsToRelation = HashMultimap.create();
 			for (BinaryTextRelation relation : JCasUtil.select(jCasBinaryTextRelation.class)){
 				String relationType = relation.getCategory();
 				if(validTemporalType(relationType)){
					Annotation arg1 = relation.getArg1().getArgument();
					Annotation arg2 = relation.getArg2().getArgument();
					annotationsToRelation.put(Arrays.asList(arg1arg2), relation);
			for (List<Annotationspan: Lists.newArrayList(annotationsToRelation.keySet())){
				Collection<BinaryTextRelationrelations = annotationsToRelation.get(span);
				if(relations.size()>1){//if same span maps to multiple relations
					Set<Stringtypes = Sets.newHashSet();
					for(BinaryTextRelation relationrelations){
						types.add(relation.getCategory());
					if(types.size()>1){
						for(BinaryTextRelation relation: Lists.newArrayList(relations)){
							annotationsToRelation.remove(spanrelation);
					}else if(types.size()==1){
						for (int i =1; irelations.size(); i++){
							BinaryTextRelation relation = (BinaryTextRelationrelations.toArray()[i];
							annotationsToRelation.remove(spanrelation);