Uploaded image for project: 'UIMA'
  1. UIMA
  2. UIMA-3724

Adding (J)CasUtil.selectCoveredSingle()

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Resolved
    • Minor
    • Resolution: Won't Fix
    • None
    • None
    • uimaFIT

    Description

      JCasUtil (and its equivalent CASUtil) have two very useful methods:

      • selectSingle(JCas jCas, Class<T> type), retrieving all T type annotations from the CAS, making sure only one exists, and returning it
      • selectCovered(JCas jCas, final Class<T> type, AnnotationFS coveringAnnotation), retrieving all T type annotations from the CAS, that exist in the span defined by the covering annotation.

      My request is to add a selectCoveredSingle method (I already implemented and tested, written below). It would retrieve all T type annotation in the span of the covering annotation, make sure there is only one, and return it.
      The uses for such a method would be really common, as this assists in performing something very basic in UIMA - once you have some annotation, you want to retrieve other information on it, and if it is a small unit, then you know in advance that many types of information should only appear once for that annotation. Otherwise, it's an error.
      For instance, say I have linguistically annotated text, and I hold some intersting annotation of a Token. Then I want to find out what is its Part Of Speech. Then I would simply call: selectCoveredSingle(jcas, PartOfSpeech.class, token), and get exactly one PartOfSpeech annotation as I expected. If there is none or more then one, an exception is thrown.

      One could also use a method like selectCoveredSingleOptional (not implemented yet), that does exactly the same, but returns null when no such annotation exists, instead of throwing an exception. This makes sense when a token can have some optional attribute. In linguistics, it could be when a Token may be a NamedEntity, but not necessarily.

      the implementation is made out of two methods - the first should be in JCasUtil, the second should be in CASUtil.
      ===
      Implementation:
      ===

      /**

      • Get the annotation of the given annotation type constrained by a 'covering' annotation.
      • Iterates over all annotations of the given type to find the covered annotations.
      • Does not use subiterators.
        *
      • @param <T>
      • the JCas type.
      • @param jCas
      • a JCas containing the annotation.
      • @param type
      • a UIMA type.
      • @param coveringAnnotation
      • the covering annotation.
      • @return the single instance of the given type.
      • @throws IllegalArgumentException if not exactly one instance if the given type is present
      • under the covering annotation.
      • @see Subiterator
      • @author Ofer Bronstein
      • @since April 2014
        */
        @SuppressWarnings("unchecked")
        public static <T extends Annotation> T selectCoveredSingle(JCas jCas, final Class<T> type,
        AnnotationFS coveringAnnotation) { return (T) selectCoveredSingle(jCas.getCas(), JCasUtil.getType(jCas, type), coveringAnnotation); }

      /**

      • Get the annotation of the given annotation type constrained by a 'covering' annotation.
      • Iterates over all annotations of the given type to find the covered annotations.
      • Does not use subiterators.
        *
      • @param cas
      • a cas containing the annotation.
      • @param type
      • a UIMA type.
      • @param coveringAnnotation
      • the covering annotation.
      • @return the single instance of the given type.
      • @throws IllegalArgumentException if not exactly one instance if the given type is present
      • under the covering annotation.
      • @see Subiterator
      • @author Ofer Bronstein
      • @since April 2014
        */
        public static AnnotationFS selectCoveredSingle(CAS cas, Type type,
        AnnotationFS coveringAnnotation) {
        List<AnnotationFS> annotations = CasUtil.selectCovered(cas, type, coveringAnnotation);

      if (annotations.isEmpty())

      { throw new IllegalArgumentException("CAS does not contain any [" + type.getName() + "]"); }

      if (annotations.size() > 1)

      { throw new IllegalArgumentException("CAS contains more than one [" + type.getName() + "]"); }

      return annotations.get(0);
      }

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              oferbr Ofer Bronstein
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Time Tracking

                  Estimated:
                  Original Estimate - 5m
                  5m
                  Remaining:
                  Remaining Estimate - 5m
                  5m
                  Logged:
                  Time Spent - Not Specified
                  Not Specified