001 /*
002 * The contents of this file are subject to the Mozilla Public
003 * License Version 1.1 (the "License"); you may not use this file
004 * except in compliance with the License. You may obtain a copy of
005 * the License at http://www.mozilla.org/MPL/
006 *
007 * Software distributed under the License is distributed on an "AS
008 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
009 * implied. See the License for the specific language governing
010 * rights and limitations under the License.
011 *
012 * The Original Code is Knowtator.
013 *
014 * The Initial Developer of the Original Code is University of Colorado.
015 * Copyright (C) 2005 - 2008. All Rights Reserved.
016 *
017 * Knowtator was developed by the Center for Computational Pharmacology
018 * (http://compbio.uchcs.edu) at the University of Colorado Health
019 * Sciences Center School of Medicine with support from the National
020 * Library of Medicine.
021 *
022 * Current information about Knowtator can be obtained at
023 * http://knowtator.sourceforge.net/
024 *
025 * Contributor(s):
026 * Philip V. Ogren <philip@ogren.info> (Original Author)
027 */
028 package edu.uchsc.ccp.iaa.matcher;
029
030 import java.util.ArrayList;
031 import java.util.HashSet;
032 import java.util.List;
033 import java.util.Set;
034
035 import edu.uchsc.ccp.iaa.Annotation;
036 import edu.uchsc.ccp.iaa.IAA;
037
038 public class SpansExactComplexFeatureMatcher implements Matcher {
039 // public static final String FEATURE_NAMES =
040 // SpansExactComplexFeatureMatcher.class.getName()+".FEATURE_NAMES";
041
042 String featureName;
043
044 int spanComplexFeatureComparison;
045
046 int classComplexFeatureComparison;
047
048 int simpleFeatureComplexFeatureComparison;
049
050 boolean allowTrivialSimpleFeatureMatches;
051
052 /**
053 * This method will return an annotation that has the exact same spans and
054 * complex features. It is not required that the annotation class match.
055 * Preference will be given to an annotation that has the same class as well
056 * as spans and simple features. If one does not exist, then null is
057 * returned.
058 */
059 public Annotation match(Annotation annotation, String compareSetName, Set<Annotation> excludeAnnotations, IAA iaa,
060 MatchResult matchResult) {
061 return match(annotation, compareSetName, iaa, excludeAnnotations, matchResult);
062 }
063
064 /**
065 * This method will return an annotation that has the exact same spans and
066 * simple features. It is not required that the annotation class match.
067 * Preference will be given to an annotation that has the same class as well
068 * as spans and simple features. If one does not exist, then null is
069 * returned.
070 *
071 * @param annotation
072 * @param compareSetName
073 * @param iaa
074 * @param excludeAnnotations
075 * @param matchResult
076 * will be set to:
077 * <ul>
078 * <li>TRIVIAL_NONMATCH if there are no exactly overlapping
079 * annotations with the passed in annotation
080 * <li>NONTRIVIAL_MATCH if there is an annotation that is exactly
081 * overlapping and the Annotation.compareSimpleFeatures returns
082 * NONTRIVIAL_MATCH
083 * <li>TRIVIAL_MATCH if there is an annotation that is exactly
084 * overlapping and the Annotation.compareSimpleFeatures returns
085 * TRIVIAL_MATCH <br>
086 * Note: if there is a trivial_match then there cannot possibly
087 * be a NONTRIVIAL_MATCH because one of the simple features of
088 * the passed in annotation must have a null value or there are
089 * no simple features.
090 * <li>NONTRIVIAL_NONMATCH if there an annotation that is exactly
091 * overlapping and the Annotation.compareSimpleFeatures returns
092 * NONTRIVIAL_NONMATCH
093 * <li>TRIVIAL_NONMATCH if there is no match or non-trivial
094 * non-match found.
095 * @return will return the first nontrivial match that it finds preferring
096 * @see edu.uchsc.ccp.iaa.matcher.Matcher#match(Annotation, String, Set,
097 * IAA, MatchResult)
098 * @see edu.uchsc.ccp.iaa.matcher.MatchResult#NONTRIVIAL_MATCH
099 * @see edu.uchsc.ccp.iaa.matcher.MatchResult#NONTRIVIAL_NONMATCH
100 * @see edu.uchsc.ccp.iaa.matcher.MatchResult#TRIVIAL_MATCH
101 * @see edu.uchsc.ccp.iaa.matcher.MatchResult#TRIVIAL_NONMATCH
102 */
103
104 public static Annotation match(Annotation annotation, String compareSetName, IAA iaa,
105 Set<Annotation> excludeAnnotations, MatchResult matchResult) {
106 // prefer class and span matches over just span matches
107 Set<Annotation> classAndSpanMatches = ClassAndSpanMatcher.matches(annotation, compareSetName, iaa,
108 excludeAnnotations, false); // no need to remove
109 // excludeAnnotations because they
110 // have already been removed by
111 // ClassAndSpanMatcher
112 Set<Annotation> exactlyOverlappingAnnotations = new HashSet<Annotation>(iaa.getExactlyOverlappingAnnotations(
113 annotation, compareSetName));
114 exactlyOverlappingAnnotations.removeAll(classAndSpanMatches);
115 exactlyOverlappingAnnotations.removeAll(excludeAnnotations);
116
117 List<Annotation> candidateAnnotations = new ArrayList<Annotation>(classAndSpanMatches.size()
118 + exactlyOverlappingAnnotations.size());
119 candidateAnnotations.addAll(classAndSpanMatches);
120 candidateAnnotations.addAll(exactlyOverlappingAnnotations);
121
122 boolean nontrivialNonmatch = false;
123
124 // for(Annotation candidateAnnotation : candidateAnnotations)
125 // {
126 // int result = Annotation.compareComplexFeature(annotation,
127 // candidateAnnotation, );
128 // if there is a trivial_match then there cannot possibly be a
129 // NONTRIVIAL_MATCH
130 // because one of the simple features of the passed in annotation must
131 // have a null value
132 // or there are no simple features.
133 // if(result == MatchResult.NONTRIVIAL_MATCH ||
134 // result == MatchResult.TRIVIAL_MATCH)
135 // {
136 // matchResult.setResult(result);
137 // return candidateAnnotation;
138 // }
139 // if(result == MatchResult.NONTRIVIAL_NONMATCH)
140 // {
141 // nontrivialNonmatch = true;
142 // }
143 // }
144
145 if (nontrivialNonmatch)
146 matchResult.setResult(MatchResult.NONTRIVIAL_NONMATCH);
147 else
148 matchResult.setResult(MatchResult.TRIVIAL_NONMATCH);
149 return null;
150 }
151
152 public String getName() {
153 return "Simple slots matcher (with same spans)";
154 }
155
156 public String getDescription() {
157 return "Annotations match if they have the same spans and the same value for simple slots (e.g. slots that are primitive values such as integer and String). Only slots that are specified must match.";
158 }
159
160 public boolean returnsTrivials() {
161 return true;
162 }
163
164 }