AbstractCoreferencer.java
001 /*
002  *  AbstractCoreferencer.java
003  *
004  *  Copyright (c) 1995-2012, The University of Sheffield. See the file
005  *  COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
006  *
007  *  This file is part of GATE (see http://gate.ac.uk/), and is free
008  *  software, licenced under the GNU Library General Public License,
009  *  Version 2, June 1991 (in the distribution as file licence.html,
010  *  and also available at http://gate.ac.uk/gate/licence.html).
011  *
012  *  $Id: AbstractCoreferencer.java 17588 2014-03-08 07:50:36Z markagreenwood $
013  */
014 
015 package gate.creole.coref;
016 
017 import gate.Annotation;
018 import gate.AnnotationSet;
019 import gate.Document;
020 import gate.FeatureMap;
021 import gate.ProcessingResource;
022 import gate.Resource;
023 import gate.creole.AbstractLanguageAnalyser;
024 import gate.creole.ResourceInstantiationException;
025 import gate.util.GateRuntimeException;
026 import gate.util.SimpleFeatureMapImpl;
027 
028 import java.util.ArrayList;
029 import java.util.HashMap;
030 import java.util.Iterator;
031 import java.util.List;
032 import java.util.Map;
033 
034 public abstract class AbstractCoreferencer extends AbstractLanguageAnalyser
035     implements ProcessingResource{
036 
037   private static final long serialVersionUID = 7077378848676784207L;
038 
039   public static final String COREF_DOCUMENT_PARAMETER_NAME = "document";
040 
041   public static final String COREF_ANN_SET_PARAMETER_NAME = "annotationSetName";
042 
043   public static final String COREF_TYPE_FEATURE_NAME = "ENTITY_MENTION_TYPE";
044   public static final String COREF_ANTECEDENT_FEATURE_NAME = "antecedent_offset";
045 
046   /** --- */
047   private static final boolean DEBUG = false;
048 
049   public String coreferenceType;
050 
051   /** --- */
052   public AbstractCoreferencer(String type) {
053     this.coreferenceType = type;
054   }
055 
056 
057   /** Initialise this resource, and return it. */
058   @Override
059   public Resource init() throws ResourceInstantiationException {
060 
061     Resource result = super.init();
062 
063     return result;
064   // init()
065 
066 
067   /**
068    * Reinitialises the processing resource. After calling this method the
069    * resource should be in the state it is after calling init.
070    * If the resource depends on external resources (such as rules files) then
071    * the resource will re-read those resources. If the data used to create
072    * the resource has changed since the resource has been created then the
073    * resource will change too after calling reInit().
074   */
075   @Override
076   public void reInit() throws ResourceInstantiationException {
077     init();
078   // reInit()
079 
080   /** Set the document to run on. */
081   @Override
082   public void setDocument(Document newDocument) {
083     super.setDocument(newDocument);
084   }
085 
086   /** --- */
087   public abstract void setAnnotationSetName(String annotationSetName);
088 
089   /** --- */
090   public abstract String getAnnotationSetName();
091 
092   /** --- */
093   protected void generateCorefChains(Map<Annotation, Annotation> ana2ant)
094       throws GateRuntimeException{
095 
096     String asName = getAnnotationSetName();
097     AnnotationSet outputSet = null;
098 
099     if (null == asName || asName.equals("")) {
100       outputSet = getDocument().getAnnotations();
101     }
102     else {
103       outputSet = getDocument().getAnnotations(asName);
104     }
105 
106     //3. generate new annotations
107     Iterator<Map.Entry<Annotation, Annotation>> it = ana2ant.entrySet().iterator();
108     while (it.hasNext()) {
109       Map.Entry<Annotation, Annotation> currLink = it.next();
110       Annotation anaphor = currLink.getKey();
111       Annotation antecedent = currLink.getValue();
112 
113       if (DEBUG) {
114         AnnotationSet corefSet = getDocument().getAnnotations("COREF");
115         Long antOffset = new Long(0);
116 
117         if (null != antecedent) {
118           antOffset = antecedent.getStartNode().getOffset();
119         }
120 
121         FeatureMap features = new SimpleFeatureMapImpl();
122         features.put("antecedent",antOffset);
123         corefSet.add(anaphor.getStartNode(),anaphor.getEndNode(),"COREF",features);
124       }
125 
126       //do we have antecedent?
127       if (null == antecedent) {
128         continue;
129       }
130 
131       //get the ortho-matches of the antecedent
132       @SuppressWarnings("unchecked")
133       List<Integer> matches = (List<Integer>)antecedent.getFeatures().
134         get(ANNOTATION_COREF_FEATURE_NAME);
135       if (null == matches) {
136         matches = new ArrayList<Integer>();
137         matches.add(antecedent.getId());
138         antecedent.getFeatures().
139           put(ANNOTATION_COREF_FEATURE_NAME,matches);
140         //check if the document has a list of matches
141         //if yes, simply add the new list to it
142         //if not, create it and add the list of matches to it
143         if (document.getFeatures().containsKey(
144             DOCUMENT_COREF_FEATURE_NAME)) {
145           @SuppressWarnings("unchecked")
146           Map<String,List<List<Integer>>> matchesMap = (Map<String,List<List<Integer>>>)document.getFeatures().get(
147                                 DOCUMENT_COREF_FEATURE_NAME);
148           List<List<Integer>> matchesList = matchesMap.get(getAnnotationSetName());
149           if (matchesList == null) {
150             matchesList = new ArrayList<List<Integer>>();
151             matchesMap.put(getAnnotationSetName(), matchesList);
152           }
153           matchesList.add(matches);
154         else {
155           Map<String,List<List<Integer>>> matchesMap = new HashMap<String,List<List<Integer>>>();
156             List<List<Integer>> matchesList = new ArrayList<List<Integer>>();
157             matchesMap.put(getAnnotationSetName(), matchesList);
158             matchesList.add(matches);
159         }//if else
160       }//if matches == null
161 
162       FeatureMap features = new SimpleFeatureMapImpl();
163       features.put(COREF_TYPE_FEATURE_NAME, coreferenceType);
164       features.put(ANNOTATION_COREF_FEATURE_NAME, matches);
165       features.put(COREF_ANTECEDENT_FEATURE_NAME,
166                    antecedent.getStartNode().getOffset());
167 
168       Integer annID = outputSet.add(anaphor.getStartNode(),
169                                     anaphor.getEndNode(),
170                                     antecedent.getType(),
171                                     features);
172       matches.add(annID);
173     }
174   }
175 
176 }