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    package edu.uchsc.ccp.iaa;
030    
031    import java.util.Collection;
032    import java.util.HashMap;
033    import java.util.HashSet;
034    import java.util.List;
035    import java.util.Map;
036    import java.util.Set;
037    
038    /**
039     * This class creates an index on a collection of annotations based on the
040     * proximity of the spans of the annotations.
041     * 
042     */
043    
044    public class AnnotationSpanIndex {
045    
046            Map<Integer, Set<Annotation>> window2AnnotationsMap;
047    
048            int windowSize;
049    
050            public AnnotationSpanIndex(Collection<Annotation> annotations) {
051                    this(annotations, 20);
052            }
053    
054            public AnnotationSpanIndex(Collection<Annotation> annotations, int windowSize) {
055                    this.windowSize = windowSize;
056                    window2AnnotationsMap = new HashMap<Integer, Set<Annotation>>();
057                    for (Annotation annotation : annotations) {
058                            List<Span> spans = annotation.getSpans();
059                            for (Span span : spans) {
060                                    int startKey = span.getStart() / windowSize;
061                                    int endKey = span.getEnd() / windowSize;
062                                    for (int key = startKey; key <= endKey; key++) {
063                                            addToMap(key, annotation);
064                                    }
065                            }
066                    }
067    
068                    // for(Integer window : window2AnnotationsMap.keySet())
069                    // {
070                    // Set<Annotation> windowAnnotations =
071                    // window2AnnotationsMap.get(window);
072                    // for(Annotation windowAnnotation : windowAnnotations)
073                    // {
074                    // Collection<Span> spans = windowAnnotation.getSpans();
075                    // }
076                    // }
077            }
078    
079            private void addToMap(int key, Annotation annotation) {
080                    if (!window2AnnotationsMap.containsKey(key)) {
081                            window2AnnotationsMap.put(key, new HashSet<Annotation>());
082                    }
083                    window2AnnotationsMap.get(key).add(annotation);
084            }
085    
086            public Set<Annotation> getNearbyAnnotations(Annotation annotation) {
087                    Collection<Span> spans = annotation.getSpans();
088                    HashSet<Integer> windows = new HashSet<Integer>();
089                    for (Span span : spans) {
090                            windows.add(new Integer(span.getStart() / windowSize));
091                            windows.add(new Integer(span.getEnd() / windowSize));
092                    }
093    
094                    HashSet<Annotation> returnValues = new HashSet<Annotation>();
095                    for (Integer window : windows) {
096                            Set<Annotation> windowAnnotations = window2AnnotationsMap.get(window);
097                            if (windowAnnotations != null)
098                                    returnValues.addAll(windowAnnotations);
099                    }
100    
101                    returnValues.remove(annotation);
102                    return returnValues;
103            }
104    
105            public Set<Annotation> getOverlappingAnnotations(Annotation annotation) {
106                    Set<Annotation> nearbyAnnotations = getNearbyAnnotations(annotation);
107                    Set<Annotation> returnValues = new HashSet<Annotation>();
108                    for (Annotation nearbyAnnotation : nearbyAnnotations) {
109                            if (Annotation.spansOverlap(annotation, nearbyAnnotation)) {
110                                    returnValues.add(nearbyAnnotation);
111                            }
112                    }
113                    return returnValues;
114            }
115    
116            public Set<Annotation> getExactlyOverlappingAnnotations(Annotation annotation) {
117                    Set<Annotation> nearbyAnnotations = getNearbyAnnotations(annotation);
118                    Set<Annotation> returnValues = new HashSet<Annotation>();
119                    for (Annotation nearbyAnnotation : nearbyAnnotations) {
120                            if (Annotation.spansMatch(annotation, nearbyAnnotation)) {
121                                    returnValues.add(nearbyAnnotation);
122                            }
123                    }
124                    return returnValues;
125            }
126    
127    }