Search in sources :

Example 36 with FeatureStructure

use of org.apache.uima.cas.FeatureStructure in project webanno by webanno.

the class ChainAdapter method deleteSpan.

private void deleteSpan(JCas aJCas, int aAddress) {
    Type chainType = getAnnotationType(aJCas.getCas());
    AnnotationFS linkToDelete = WebAnnoCasUtil.selectByAddr(aJCas, AnnotationFS.class, aAddress);
    // case 1 "removing first link": we keep the existing chain head and just remove the
    // first element
    // 
    // case 2 "removing middle link": the new chain consists of the rest, the old chain head
    // remains
    // 
    // case 3 "removing the last link": the old chain head remains and the last element of the
    // chain is removed.
    // To know which case we have, we first need to find the chain containing the element to
    // be deleted.
    FeatureStructure oldChainFs = null;
    AnnotationFS prevLinkFs = null;
    chainLoop: for (FeatureStructure chainFs : selectFS(aJCas.getCas(), chainType)) {
        AnnotationFS linkFs = getFirstLink(chainFs);
        // Reset when entering new chain!
        prevLinkFs = null;
        // Now we seek the link within the current chain
        while (linkFs != null) {
            if (WebAnnoCasUtil.isSame(linkFs, linkToDelete)) {
                oldChainFs = chainFs;
                break chainLoop;
            }
            prevLinkFs = linkFs;
            linkFs = getNextLink(linkFs);
        }
    }
    // Did we find the chain?!
    if (oldChainFs == null) {
        throw new IllegalArgumentException("Chain link with address [" + aAddress + "] not found in any chain!");
    }
    AnnotationFS followingLinkToDelete = getNextLink(linkToDelete);
    if (prevLinkFs == null) {
        // case 1: first element removed
        setFirstLink(oldChainFs, followingLinkToDelete);
        aJCas.removeFsFromIndexes(linkToDelete);
        // removed last element form chain?
        if (followingLinkToDelete == null) {
            aJCas.removeFsFromIndexes(oldChainFs);
        }
    } else if (followingLinkToDelete == null) {
        // case 3: removing the last link (but not leaving the chain empty)
        setNextLink(prevLinkFs, null);
        aJCas.removeFsFromIndexes(linkToDelete);
    } else if (prevLinkFs != null && followingLinkToDelete != null) {
        // case 2: removing a middle link
        // Set up new chain for rest
        newChain(aJCas, followingLinkToDelete);
        // Cut off from old chain
        setNextLink(prevLinkFs, null);
        // Delete middle link
        aJCas.removeFsFromIndexes(linkToDelete);
    } else {
        throw new IllegalStateException("Unexpected situation while removing link. Please contact developers.");
    }
}
Also used : FeatureStructure(org.apache.uima.cas.FeatureStructure) AnnotationFS(org.apache.uima.cas.text.AnnotationFS) Type(org.apache.uima.cas.Type)

Example 37 with FeatureStructure

use of org.apache.uima.cas.FeatureStructure in project webanno by webanno.

the class FeatureSupport method setFeatureValue.

/**
 * Update this feature with a new value. This method should not be called directly but
 * rather via {@link TypeAdapter#setFeatureValue}.
 *
 * @param aJcas
 *            the JCas.
 * @param aFeature
 *            the feature.
 * @param aAddress
 *            the annotation ID.
 * @param aValue
 *            the value.
 */
default void setFeatureValue(JCas aJcas, AnnotationFeature aFeature, int aAddress, Object aValue) {
    FeatureStructure fs = selectByAddr(aJcas, FeatureStructure.class, aAddress);
    setFeature(fs, aFeature, aValue);
}
Also used : FeatureStructure(org.apache.uima.cas.FeatureStructure)

Example 38 with FeatureStructure

use of org.apache.uima.cas.FeatureStructure in project webanno by webanno.

the class MergeCas method reMergeCas.

/**
 * Using {@code DiffResult}, determine the annotations to be deleted from the randomly generated
 * MergeCase. The initial Merge CAs is stored under a name {@code CurationPanel#CURATION_USER}.
 * <p>
 * Any similar annotations stacked in a {@code CasDiff2.Position} will be assumed a difference
 * <p>
 * Any two annotation with different value will be assumed a difference
 * <p>
 * Any non stacked empty/null annotations are assumed agreement
 * <p>
 * Any non stacked annotations with similar values for each of the features are assumed
 * agreement
 * <p>
 * Any two link mode / slotable annotations which agree on the base features are assumed
 * agreement
 *
 * @param aDiff
 *            the {@code CasDiff2.DiffResult}
 * @param aJCases
 *            a map of{@code JCas}s for each users and the random merge
 * @return the actual merge {@code JCas}
 */
public static JCas reMergeCas(DiffResult aDiff, Map<String, JCas> aJCases) {
    Set<FeatureStructure> slotFeaturesToReset = new HashSet<>();
    Set<FeatureStructure> annotationsToDelete = new HashSet<>();
    Set<String> users = aJCases.keySet();
    for (Position position : aDiff.getPositions()) {
        Map<String, List<FeatureStructure>> annosPerUser = new HashMap<>();
        ConfigurationSet cfgs = aDiff.getConfigurtionSet(position);
        if (cfgs.getConfigurations(WebAnnoConst.CURATION_USER).isEmpty()) {
            // annotations
            continue;
        }
        AnnotationFS mergeAnno = (AnnotationFS) cfgs.getConfigurations(WebAnnoConst.CURATION_USER).get(0).getFs(WebAnnoConst.CURATION_USER, aJCases);
        // Get Annotations per user in this position
        getAllAnnosOnPosition(aJCases, annosPerUser, users, mergeAnno);
        for (FeatureStructure mergeFs : annosPerUser.get(WebAnnoConst.CURATION_USER)) {
            // incomplete annotations
            if (aJCases.size() != annosPerUser.size()) {
                annotationsToDelete.add(mergeFs);
            } else // agreed and not stacked
            if (isAgree(mergeFs, annosPerUser)) {
                Type t = mergeFs.getType();
                Feature sourceFeat = t.getFeatureByBaseName(WebAnnoConst.FEAT_REL_SOURCE);
                Feature targetFeat = t.getFeatureByBaseName(WebAnnoConst.FEAT_REL_TARGET);
                // Is this a relation?
                if (sourceFeat != null && targetFeat != null) {
                    AnnotationFS source = (AnnotationFS) mergeFs.getFeatureValue(sourceFeat);
                    AnnotationFS target = (AnnotationFS) mergeFs.getFeatureValue(targetFeat);
                    // all span anno on this source positions
                    Map<String, List<FeatureStructure>> sourceAnnosPerUser = new HashMap<>();
                    // all span anno on this target positions
                    Map<String, List<FeatureStructure>> targetAnnosPerUser = new HashMap<>();
                    getAllAnnosOnPosition(aJCases, sourceAnnosPerUser, users, source);
                    getAllAnnosOnPosition(aJCases, targetAnnosPerUser, users, target);
                    if (isAgree(source, sourceAnnosPerUser) && isAgree(target, targetAnnosPerUser)) {
                        slotFeaturesToReset.add(mergeFs);
                    } else {
                        annotationsToDelete.add(mergeFs);
                    }
                } else {
                    slotFeaturesToReset.add(mergeFs);
                }
            } else // disagree or stacked annotations
            {
                annotationsToDelete.add(mergeFs);
            }
        // remove dangling rels
        // setDanglingRelToDel(aJCases.get(CurationPanel.CURATION_USER),
        // mergeFs, annotationsToDelete);
        }
    }
    // remove annotations that do not agree or are a stacked ones
    for (FeatureStructure fs : annotationsToDelete) {
        if (!slotFeaturesToReset.contains(fs)) {
            JCas mergeCas = aJCases.get(WebAnnoConst.CURATION_USER);
            // Check if this difference is on POS, STEM and LEMMA (so remove from the token too)
            Type type = fs.getType();
            int fsBegin = ((AnnotationFS) fs).getBegin();
            int fsEnd = ((AnnotationFS) fs).getEnd();
            if (type.getName().equals(POS.class.getName())) {
                Token t = JCasUtil.selectCovered(mergeCas, Token.class, fsBegin, fsEnd).get(0);
                t.setPos(null);
            }
            if (type.getName().equals(Stem.class.getName())) {
                Token t = JCasUtil.selectCovered(mergeCas, Token.class, fsBegin, fsEnd).get(0);
                t.setStem(null);
            }
            if (type.getName().equals(Lemma.class.getName())) {
                Token t = JCasUtil.selectCovered(mergeCas, Token.class, fsBegin, fsEnd).get(0);
                t.setLemma(null);
            }
            if (type.getName().equals(MorphologicalFeatures.class.getName())) {
                Token t = JCasUtil.selectCovered(mergeCas, Token.class, fsBegin, fsEnd).get(0);
                t.setMorph(null);
            }
            mergeCas.removeFsFromIndexes(fs);
        }
    }
    // if slot bearing annotation, clean
    for (FeatureStructure baseFs : slotFeaturesToReset) {
        for (Feature roleFeature : baseFs.getType().getFeatures()) {
            if (isLinkMode(baseFs, roleFeature)) {
                // FeatureStructure roleFs = baseFs.getFeatureValue(f);
                ArrayFS roleFss = (ArrayFS) WebAnnoCasUtil.getFeatureFS(baseFs, roleFeature.getShortName());
                if (roleFss == null) {
                    continue;
                }
                Map<String, ArrayFS> roleAnnosPerUser = new HashMap<>();
                setAllRoleAnnosOnPosition(aJCases, roleAnnosPerUser, users, baseFs, roleFeature);
                List<FeatureStructure> linkFSes = new LinkedList<>(Arrays.asList(roleFss.toArray()));
                for (FeatureStructure roleFs : roleFss.toArray()) {
                    if (isRoleAgree(roleFs, roleAnnosPerUser)) {
                        for (Feature targetFeature : roleFs.getType().getFeatures()) {
                            if (isBasicFeature(targetFeature)) {
                                continue;
                            }
                            if (!targetFeature.getShortName().equals("target")) {
                                continue;
                            }
                            AnnotationFS targetFs = (AnnotationFS) roleFs.getFeatureValue(targetFeature);
                            if (targetFs == null) {
                                continue;
                            }
                            Map<String, List<FeatureStructure>> targetAnnosPerUser = new HashMap<>();
                            getAllAnnosOnPosition(aJCases, targetAnnosPerUser, users, targetFs);
                            // do not agree on targets
                            if (!isAgree(targetFs, targetAnnosPerUser)) {
                                linkFSes.remove(roleFs);
                            }
                        }
                    } else // do not agree on some role features
                    {
                        linkFSes.remove(roleFs);
                    }
                }
                ArrayFS array = baseFs.getCAS().createArrayFS(linkFSes.size());
                array.copyFromArray(linkFSes.toArray(new FeatureStructure[linkFSes.size()]), 0, 0, linkFSes.size());
                baseFs.setFeatureValue(roleFeature, array);
            }
        }
    }
    return aJCases.get(WebAnnoConst.CURATION_USER);
}
Also used : HashMap(java.util.HashMap) JCas(org.apache.uima.jcas.JCas) Token(de.tudarmstadt.ukp.dkpro.core.api.segmentation.type.Token) Feature(org.apache.uima.cas.Feature) WebAnnoCasUtil.setFeature(de.tudarmstadt.ukp.clarin.webanno.api.annotation.util.WebAnnoCasUtil.setFeature) AnnotationFeature(de.tudarmstadt.ukp.clarin.webanno.model.AnnotationFeature) Stem(de.tudarmstadt.ukp.dkpro.core.api.segmentation.type.Stem) FeatureStructure(org.apache.uima.cas.FeatureStructure) AnnotationFS(org.apache.uima.cas.text.AnnotationFS) Lemma(de.tudarmstadt.ukp.dkpro.core.api.segmentation.type.Lemma) LinkedList(java.util.LinkedList) List(java.util.List) HashSet(java.util.HashSet) MorphologicalFeatures(de.tudarmstadt.ukp.dkpro.core.api.lexmorph.type.morph.MorphologicalFeatures) Position(de.tudarmstadt.ukp.clarin.webanno.curation.casdiff.CasDiff2.Position) LinkedList(java.util.LinkedList) ConfigurationSet(de.tudarmstadt.ukp.clarin.webanno.curation.casdiff.CasDiff2.ConfigurationSet) Type(org.apache.uima.cas.Type) POS(de.tudarmstadt.ukp.dkpro.core.api.lexmorph.type.pos.POS) ArrayFS(org.apache.uima.cas.ArrayFS) HashMap(java.util.HashMap) Map(java.util.Map)

Example 39 with FeatureStructure

use of org.apache.uima.cas.FeatureStructure in project webanno by webanno.

the class MergeCas method isSameAnno.

/**
 * Return true if these two annotations agree on every non slot features
 */
private static boolean isSameAnno(FeatureStructure aFirstFS, FeatureStructure aSeconFS) {
    for (Feature f : getAllFeatures(aFirstFS)) {
        // the annotations are already in the same position
        if (isBasicFeature(f)) {
            continue;
        }
        if (!isLinkMode(aFirstFS, f)) {
            // check if attache type exists
            try {
                FeatureStructure attachFs1 = aFirstFS.getFeatureValue(f);
                FeatureStructure attachFs2 = aSeconFS.getFeatureValue(f);
                if (!isSameAnno(attachFs1, attachFs2)) {
                    return false;
                }
            } catch (Exception e) {
            // no attach type -- continue
            }
            // assume null as equal
            if (getFeatureValue(aFirstFS, f) == null && getFeatureValue(aSeconFS, f) == null) {
                continue;
            }
            if (getFeatureValue(aFirstFS, f) == null && getFeatureValue(aSeconFS, f) != null) {
                return false;
            }
            if (getFeatureValue(aFirstFS, f) != null && getFeatureValue(aSeconFS, f) == null) {
                return false;
            }
            if (!getFeatureValue(aFirstFS, f).equals(getFeatureValue(aSeconFS, f))) {
                return false;
            }
        }
    }
    return true;
}
Also used : FeatureStructure(org.apache.uima.cas.FeatureStructure) Feature(org.apache.uima.cas.Feature) WebAnnoCasUtil.setFeature(de.tudarmstadt.ukp.clarin.webanno.api.annotation.util.WebAnnoCasUtil.setFeature) AnnotationFeature(de.tudarmstadt.ukp.clarin.webanno.model.AnnotationFeature) AnnotationException(de.tudarmstadt.ukp.clarin.webanno.api.annotation.exception.AnnotationException)

Example 40 with FeatureStructure

use of org.apache.uima.cas.FeatureStructure in project webanno by webanno.

the class CopyAnnotationTest method copyLinkToEmptyTest.

@Test
public void copyLinkToEmptyTest() throws Exception {
    JCas mergeCAs = JCasFactory.createJCas(DiffUtils.createMultiLinkWithRoleTestTypeSytem("f1"));
    Type type = mergeCAs.getTypeSystem().getType(DiffUtils.HOST_TYPE);
    Feature feature = type.getFeatureByBaseName("f1");
    AnnotationFS mergeFs = DiffUtils.makeLinkHostMultiSPanFeatureFS(mergeCAs, 0, 0, feature, "A");
    FeatureStructure copyFS = DiffUtils.makeLinkFS(mergeCAs, "slot1", 0, 0);
    List<FeatureStructure> linkFs = new ArrayList<>();
    linkFs.add(copyFS);
    WebAnnoCasUtil.setLinkFeatureValue(mergeFs, type.getFeatureByBaseName("links"), linkFs);
    JCas jcasA = JCasFactory.createJCas(DiffUtils.createMultiLinkWithRoleTestTypeSytem("f1"));
    DiffUtils.makeLinkHostMultiSPanFeatureFS(jcasA, 0, 0, feature, "A", DiffUtils.makeLinkFS(jcasA, "slot1", 0, 0));
    Map<String, List<JCas>> casByUser = new LinkedHashMap<>();
    casByUser.put("user1", asList(mergeCAs));
    casByUser.put("user2", asList(jcasA));
    List<String> entryTypes = asList(DiffUtils.HOST_TYPE);
    CasDiff2.SpanDiffAdapter adapter = new CasDiff2.SpanDiffAdapter(DiffUtils.HOST_TYPE);
    adapter.addLinkFeature("links", "role", "target");
    List<? extends CasDiff2.DiffAdapter> diffAdapters = asList(adapter);
    CasDiff2.DiffResult diff = CasDiff2.doDiff(entryTypes, diffAdapters, CasDiff2.LinkCompareBehavior.LINK_TARGET_AS_LABEL, casByUser);
    assertEquals(0, diff.getDifferingConfigurationSets().size());
    assertEquals(0, diff.getIncompleteConfigurationSets().size());
}
Also used : CasDiff2(de.tudarmstadt.ukp.clarin.webanno.curation.casdiff.CasDiff2) ArrayList(java.util.ArrayList) JCas(org.apache.uima.jcas.JCas) Feature(org.apache.uima.cas.Feature) AnnotationFeature(de.tudarmstadt.ukp.clarin.webanno.model.AnnotationFeature) LinkedHashMap(java.util.LinkedHashMap) FeatureStructure(org.apache.uima.cas.FeatureStructure) AnnotationFS(org.apache.uima.cas.text.AnnotationFS) Type(org.apache.uima.cas.Type) ArrayList(java.util.ArrayList) Arrays.asList(java.util.Arrays.asList) List(java.util.List) Test(org.junit.Test)

Aggregations

FeatureStructure (org.apache.uima.cas.FeatureStructure)60 Type (org.apache.uima.cas.Type)38 AnnotationFS (org.apache.uima.cas.text.AnnotationFS)37 ArrayList (java.util.ArrayList)29 JCas (org.apache.uima.jcas.JCas)20 Feature (org.apache.uima.cas.Feature)17 Token (de.tudarmstadt.ukp.dkpro.core.api.segmentation.type.Token)16 CAS (org.apache.uima.cas.CAS)16 Test (org.junit.Test)16 AnnotationFeature (de.tudarmstadt.ukp.clarin.webanno.model.AnnotationFeature)13 List (java.util.List)12 ArrayFS (org.apache.uima.cas.ArrayFS)8 Arrays.asList (java.util.Arrays.asList)6 LinkedHashMap (java.util.LinkedHashMap)6 CasUtil.getType (org.apache.uima.fit.util.CasUtil.getType)6 AnnotationLayer (de.tudarmstadt.ukp.clarin.webanno.model.AnnotationLayer)5 AnnotatorState (de.tudarmstadt.ukp.clarin.webanno.api.annotation.model.AnnotatorState)4 LogMessage (de.tudarmstadt.ukp.clarin.webanno.diag.CasDoctor.LogMessage)4 TsvColumn (de.tudarmstadt.ukp.clarin.webanno.tsv.internal.tsv3x.model.TsvColumn)4 Map (java.util.Map)4