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
029 /**
030 * 8/15/2005 The type filtering was using the old Knowtator model. Changed the code
031 * so that the type and supertypes of the mention of the annotation are
032 * verified.
033 */
034 package edu.uchsc.ccp.knowtator;
035
036 import java.util.ArrayList;
037 import java.util.Collection;
038 import java.util.Collections;
039 import java.util.HashSet;
040 import java.util.Iterator;
041 import java.util.List;
042 import java.util.Set;
043
044 import org.apache.log4j.Logger;
045
046 import edu.stanford.smi.protege.model.Cls;
047 import edu.stanford.smi.protege.model.Frame;
048 import edu.stanford.smi.protege.model.Instance;
049 import edu.stanford.smi.protege.model.KnowledgeBase;
050 import edu.stanford.smi.protege.model.SimpleInstance;
051 import edu.uchsc.ccp.knowtator.util.ConsensusException;
052
053 public class FilterUtil {
054 public static final int ANY_FILTER = 0;
055
056 public static final int CONSENSUS_FILTER = 1;
057
058 public static final int NONCONSENSUS_FILTER = 2;
059
060 KnowtatorManager manager;
061
062 KnowtatorProjectUtil kpu;
063
064 AnnotationUtil annotationUtil;
065
066 MentionUtil mentionUtil;
067
068 Logger logger = Logger.getLogger(FilterUtil.class);
069
070 /** Creates a new instance of FilterUtil */
071 public FilterUtil(KnowtatorManager manager) {
072 this.manager = manager;
073 this.kpu = manager.getKnowtatorProjectUtil();
074 this.annotationUtil = manager.getAnnotationUtil();
075 this.mentionUtil = manager.getMentionUtil();
076 }
077
078 public Collection<SimpleInstance> filterAnnotations(Collection<SimpleInstance> annotationInstances,
079 SimpleInstance filterInstance) {
080 return filterAnnotations(annotationInstances, filterInstance, false);
081 }
082
083 public boolean isClsLicensedByFilter(SimpleInstance filter, Frame frame) {
084 Cls cls = null;
085 if (frame instanceof Cls)
086 cls = (Cls) frame;
087 else
088 cls = ((Instance) frame).getDirectType();
089
090 Collection goodTypes = filter.getOwnSlotValues(kpu.filterTypeSlot);
091 if (goodTypes == null || goodTypes.size() == 0)
092 return true;
093 else {
094 Collection superTypes = cls.getSuperclasses();
095 ArrayList types = new ArrayList(superTypes);
096 types.add(cls);
097 for (Iterator iterator = types.iterator(); iterator.hasNext();) {
098 if (goodTypes.contains(iterator.next())) {
099 return true;
100 }
101 }
102 }
103 return false;
104 }
105
106 /**
107 * @param textViewerSelectable
108 * - true if you want to filter out annotations of the types
109 * specified in the
110 * knowtator_types_not_selectable_from_text_viewer slot of the
111 * filter.
112 */
113 public List<SimpleInstance> filterAnnotations(Collection<SimpleInstance> annotationInstances,
114 SimpleInstance filterInstance, boolean ignoreTypeFilter, boolean textViewerSelectable) {
115 logger.debug("");
116 Collection badTypes = filterInstance.getOwnSlotValues(kpu.getFilterTypesNotSelectableFromTextViewerSlot());
117 // logger.debug("badTypes.size()="+badTypes.size());
118 List<SimpleInstance> annotations = filterAnnotations(annotationInstances, filterInstance, ignoreTypeFilter);
119 // logger.debug("annotations.size()="+annotations.size());
120 List<SimpleInstance> returnValues = new ArrayList<SimpleInstance>();
121
122 if (badTypes.size() > 0 && textViewerSelectable) {
123 for (SimpleInstance annotation : annotations) {
124 boolean goodType = true;
125 SimpleInstance mention = annotationUtil.getMention(annotation);
126 Cls mentionCls = mentionUtil.getMentionCls(mention);
127 if (mentionCls != null) {
128 Collection superTypes = mentionCls.getSuperclasses();
129 ArrayList types = new ArrayList(superTypes);
130 types.add(mentionCls);
131 // logger.debug("annotation types");
132 // for (Object object : types) {
133 // logger.debug(object);
134 // }
135 for (Iterator iterator = types.iterator(); iterator.hasNext();) {
136 if (badTypes.contains(iterator.next())) {
137 // logger.debug(
138 // "badTypes.contains superclass of annotation");
139 // logger.debug("mentionCls="+mentionCls);
140 goodType = false;
141 break;
142 }
143 }
144 if (goodType)
145 returnValues.add(annotation);
146 }
147 }
148 logger.debug("returning returnValues: " + returnValues.size());
149 return returnValues;
150 } else
151 return annotations;
152 }
153
154 /**
155 *
156 * @param annotationInstances
157 * @param filterInstance
158 * @param ignoreTypeFilter
159 * - will ignore the type of the annotation when filtering if
160 * true. If true, then the value of textviewerSelectable is
161 * ignored.
162 */
163 public List<SimpleInstance> filterAnnotations(Collection<SimpleInstance> annotationInstances,
164 SimpleInstance filterInstance, boolean ignoreTypeFilter) {
165 Collection goodAnnotators = filterInstance.getOwnSlotValues(kpu.filterAnnotatorSlot);
166 Collection goodAnnotationSets = filterInstance.getOwnSlotValues(kpu.filterSetSlot);
167 Collection goodTypes = filterInstance.getOwnSlotValues(kpu.filterTypeSlot);
168
169 ArrayList<SimpleInstance> goodAnnotations = new ArrayList<SimpleInstance>();
170
171 if (annotationInstances != null) {
172 for (SimpleInstance annotation : annotationInstances) {
173 boolean goodAnnotator = goodAnnotators.size() > 0 ? false : true;
174 boolean goodAnnotationSet = goodAnnotationSets.size() > 0 ? false : true;
175 boolean goodType = (goodTypes.size() > 0 && !ignoreTypeFilter) ? false : true;
176
177 if (goodAnnotator && goodAnnotationSet && goodType) {
178 goodAnnotations.add(annotation);
179 continue;
180 }
181
182 /**
183 * might be better to iterate through members rather than
184 * calling retainAll for performance reasons (can continue as
185 * soon as you find a match using contains)
186 */
187 if (!goodType) {
188 SimpleInstance mention = annotationUtil.getMention(annotation);
189 Cls mentionCls = mentionUtil.getMentionCls(mention);
190 if (mentionCls != null) {
191 Collection superTypes = mentionCls.getSuperclasses();
192 ArrayList types = new ArrayList(superTypes);
193 types.add(mentionCls);
194 for (Iterator iterator = types.iterator(); iterator.hasNext();) {
195 if (goodTypes.contains(iterator.next())) {
196 goodType = true;
197 break;
198 }
199 }
200 }
201 }
202 if (!goodAnnotator) {
203 Collection annotators = annotation.getOwnSlotValues(kpu.getAnnotationAnnotatorSlot());
204 for (Iterator iterator = annotators.iterator(); iterator.hasNext();) {
205 if (goodAnnotators.contains(iterator.next())) {
206 goodAnnotator = true;
207 break;
208 }
209 }
210 }
211
212 if (!goodAnnotationSet) {
213 Collection annotationSets = annotation.getOwnSlotValues(kpu.getSetSlot());
214 for (Iterator iterator = annotationSets.iterator(); iterator.hasNext();) {
215 if (goodAnnotationSets.contains(iterator.next())) {
216 goodAnnotationSet = true;
217 break;
218 }
219 }
220 }
221
222 if (goodAnnotator && goodAnnotationSet && goodType) {
223 goodAnnotations.add(annotation);
224 continue;
225 }
226 }
227 }
228
229 return goodAnnotations;
230 }
231
232 /**
233 * Returns the types specified by the filter. This method will not return
234 * null - but rather an empty set if no type has been specified by the
235 * filter.
236 */
237 public static Set<Cls> getTypes(SimpleInstance filter) {
238 KnowledgeBase kb = filter.getKnowledgeBase();
239 Collection<Cls> filterTypes = (Collection<Cls>) filter.getOwnSlotValues(kb
240 .getSlot(KnowtatorProjectUtil.FILTER_TYPE_SLOT_NAME));
241 Set<Cls> types = new HashSet<Cls>();
242 if (filterTypes != null) {
243 types.addAll(filterTypes);
244 }
245 return types;
246 }
247
248 /**
249 * Returns the annotators specified by the filter. This method will not
250 * return null - but rather an empty set if no annotator has been specified
251 * by the filter.
252 */
253 public static List<SimpleInstance> getAnnotators(SimpleInstance filter) {
254 KnowledgeBase kb = filter.getKnowledgeBase();
255 Collection<SimpleInstance> filterAnnotators = (Collection<SimpleInstance>) filter.getOwnSlotValues(kb
256 .getSlot(KnowtatorProjectUtil.FILTER_ANNOTATOR_SLOT_NAME));
257 List<SimpleInstance> annotators = new ArrayList<SimpleInstance>();
258 if (filterAnnotators != null) {
259 annotators.addAll(filterAnnotators);
260 }
261 return annotators;
262 }
263
264 public static Set<SimpleInstance> getSets(SimpleInstance filter) {
265 KnowledgeBase kb = filter.getKnowledgeBase();
266 Collection<SimpleInstance> filterSets = (Collection<SimpleInstance>) filter.getOwnSlotValues(kb
267 .getSlot(KnowtatorProjectUtil.FILTER_SET_SLOT_NAME));
268 Set<SimpleInstance> sets = new HashSet<SimpleInstance>();
269 if (filterSets != null) {
270 sets.addAll(filterSets);
271 }
272 return sets;
273 }
274
275 public static boolean isConsensusFilter(SimpleInstance filter) {
276 if (filter == null)
277 return false;
278 KnowledgeBase kb = filter.getKnowledgeBase();
279 Cls type = filter.getDirectType();
280 if (type.equals(kb.getCls(KnowtatorProjectUtil.CONSENSUS_FILTER_CLS_NAME)))
281 return true;
282 return false;
283 }
284
285 public SimpleInstance getPreviousFilter(int filterType) {
286 int currentFilterIndex = getCurrentFilterIndex();
287 List<SimpleInstance> activeFilters = new ArrayList<SimpleInstance>(manager.getActiveFilters());
288 Collections.rotate(activeFilters, activeFilters.size() - currentFilterIndex); // put
289 // current
290 // filter
291 // at
292 // begin
293 // of
294 // list
295 for (int i = activeFilters.size() - 1; i >= 0; i--) {
296 SimpleInstance filter = activeFilters.get(i);
297 if (filterType == ANY_FILTER)
298 return filter;
299 if (filterType == CONSENSUS_FILTER) {
300 if (isConsensusFilter(filter))
301 return filter;
302 }
303 if (filterType == NONCONSENSUS_FILTER) {
304 if (!isConsensusFilter(filter))
305 return filter;
306 }
307 }
308 return null;
309 }
310
311 public int getCurrentFilterIndex() {
312 SimpleInstance currentFilter = manager.getSelectedFilter();
313 List<SimpleInstance> filterInstances = manager.getActiveFilters();
314 if (currentFilter == null && filterInstances.size() > 0) {
315 return 0;
316 }
317 for (int i = 0; i < filterInstances.size(); i++) {
318 if (currentFilter.equals(filterInstances.get(i))) {
319 if (i < filterInstances.size() - 1)
320 return i;
321 else
322 return 0;
323 }
324 }
325 return -1;
326 }
327
328 /**
329 *
330 * @param filterType
331 * one of ANY_FILTER, CONSENSUS_FILTER, or NONCONSENSUS_FILTER
332 * @return the next filter of the provided type
333 */
334 public SimpleInstance getNextFilter(int filterType) {
335 int currentFilterIndex = getCurrentFilterIndex();
336 List<SimpleInstance> activeFilters = new ArrayList<SimpleInstance>(manager.getActiveFilters());
337 Collections.rotate(activeFilters, activeFilters.size() - currentFilterIndex - 1);// put
338 // current
339 // filter
340 // at
341 // end
342 // of
343 // list
344 for (int i = 0; i < activeFilters.size(); i++) {
345 SimpleInstance filter = activeFilters.get(i);
346 if (filterType == ANY_FILTER)
347 return filter;
348 if (filterType == CONSENSUS_FILTER) {
349 if (isConsensusFilter(filter))
350 return filter;
351 }
352 if (filterType == NONCONSENSUS_FILTER) {
353 if (!isConsensusFilter(filter))
354 return filter;
355 }
356 }
357 return null;
358 }
359
360 public void selectNextFilter(int filterType) throws ConsensusException {
361 logger.debug("");
362 manager.setSelectedFilter(getNextFilter(filterType));
363 }
364
365 public void selectPreviousFilter(int filterType) throws ConsensusException {
366 logger.debug("");
367 manager.setSelectedFilter(getNextFilter(filterType));
368 }
369
370 }