use of org.apache.uima.cas.Feature in project webanno by webanno.
the class CopyAnnotationTest method createPOSAnno.
private AnnotationFS createPOSAnno(JCas aJCas, Type aType, String aValue, int aBegin, int aEnd) {
AnnotationFS clickedFs = aJCas.getCas().createAnnotation(aType, aBegin, aEnd);
Feature posValue = aType.getFeatureByBaseName("PosValue");
clickedFs.setStringValue(posValue, aValue);
aJCas.addFsToIndexes(clickedFs);
return clickedFs;
}
use of org.apache.uima.cas.Feature in project webanno by webanno.
the class CopyAnnotationTest method simpleCopyToSameExistingAnnoTest.
@Test
public void simpleCopyToSameExistingAnnoTest() throws Exception {
JCas jcas = JCasFactory.createJCas();
Type type = jcas.getTypeSystem().getType(POS.class.getTypeName());
AnnotationFS clickedFs = createPOSAnno(jcas, type, "NN", 0, 0);
JCas mergeCAs = JCasFactory.createJCas();
AnnotationFS existingFs = mergeCAs.getCas().createAnnotation(type, 0, 0);
Feature posValue = type.getFeatureByBaseName("PosValue");
existingFs.setStringValue(posValue, "NN");
mergeCAs.addFsToIndexes(existingFs);
exception.expect(AnnotationException.class);
MergeCas.addSpanAnnotation(new AnnotatorStateImpl(Mode.CURATION), annotationSchemaService, posLayer, mergeCAs, clickedFs, false);
}
use of org.apache.uima.cas.Feature 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());
}
use of org.apache.uima.cas.Feature in project webanno by webanno.
the class MergeCasTest method multiLinkMultiSpanRoleDiffTest.
@Test
public void multiLinkMultiSpanRoleDiffTest() throws Exception {
JCas jcasA = JCasFactory.createJCas(DiffUtils.createMultiLinkWithRoleTestTypeSytem("f1"));
Type type = jcasA.getTypeSystem().getType(DiffUtils.HOST_TYPE);
Feature feature = type.getFeatureByBaseName("f1");
DiffUtils.makeLinkHostMultiSPanFeatureFS(jcasA, 0, 0, feature, "A", DiffUtils.makeLinkFS(jcasA, "slot1", 0, 0));
JCas jcasB = JCasFactory.createJCas(DiffUtils.createMultiLinkWithRoleTestTypeSytem("f1"));
DiffUtils.makeLinkHostMultiSPanFeatureFS(jcasB, 0, 0, feature, "A", DiffUtils.makeLinkFS(jcasB, "slot2", 0, 0));
Map<String, List<JCas>> casByUser = new LinkedHashMap<>();
casByUser.put("user1", asList(jcasA));
casByUser.put("user2", asList(jcasB));
casByUser.put(CURATION_USER, asList(jcasA));
List<String> entryTypes = asList(DiffUtils.HOST_TYPE);
SpanDiffAdapter adapter = new SpanDiffAdapter(DiffUtils.HOST_TYPE);
adapter.addLinkFeature("links", "role", "target");
List<? extends DiffAdapter> diffAdapters = asList(adapter);
DiffResult result = CasDiff2.doDiff(entryTypes, diffAdapters, LinkCompareBehavior.LINK_TARGET_AS_LABEL, casByUser);
result.print(System.out);
JCas mergeCas = MergeCas.reMergeCas(result, getSingleCasByUser(casByUser));
Type hostType = mergeCas.getTypeSystem().getType(DiffUtils.HOST_TYPE);
int numHost = CasUtil.select(mergeCas.getCas(), hostType).size();
assertEquals(1, numHost);
}
use of org.apache.uima.cas.Feature in project webanno by webanno.
the class CasDiff2 method equalsFS.
/**
* Compare two feature structure to each other. Comparison is done recursively, but stops at
* feature values that are annotations. For these, only offsets are checked, but feature values
* are not inspected further. If the annotations are relevant, their type should be added to the
* entry types and will then be checked and grouped separately.
*
* @param aFS1
* first feature structure.
* @param aFS2
* second feature structure.
* @return {@code true} if they are equal.
*/
public boolean equalsFS(FeatureStructure aFS1, FeatureStructure aFS2) {
// Trivial case
if (aFS1 == aFS2) {
return true;
}
// Null check
if (aFS1 == null || aFS2 == null) {
return false;
}
// Trivial case
if (aFS1.getCAS() == aFS2.getCAS() && getAddr(aFS1) == getAddr(aFS2)) {
return true;
}
Type type1 = aFS1.getType();
Type type2 = aFS2.getType();
// Types must be the same
if (!type1.getName().equals(type2.getName())) {
return false;
}
assert type1.getNumberOfFeatures() == type2.getNumberOfFeatures();
// Sort features by name to be independent over implementation details that may change the
// order of the features as returned from Type.getFeatures().
String[] cachedSortedFeatures = sortedFeaturesCache.get(type1.getName());
if (cachedSortedFeatures == null) {
cachedSortedFeatures = new String[type1.getNumberOfFeatures()];
int i = 0;
for (Feature f : aFS1.getType().getFeatures()) {
cachedSortedFeatures[i] = f.getShortName();
i++;
}
sortedFeaturesCache.put(type1.getName(), cachedSortedFeatures);
}
DiffAdapter adapter = typeAdapters.get(type1.getName());
if (adapter == null) {
log.warn("No diff adapter for type [" + type1.getName() + "] -- ignoring!");
return true;
}
// Only consider label features. In particular these must not include position features
// such as begin, end, etc.
List<String> sortedFeatures = new ArrayList<>(asList(cachedSortedFeatures));
Set<String> labelFeatures = adapter.getLabelFeatures();
sortedFeatures.removeIf(f -> !labelFeatures.contains(f));
if (!recurseIntoLinkFeatures) {
// #1795 Chili REC: We can/should change CasDiff2 such that it does not recurse into
// link features (or rather into any features that are covered by their own
// sub-positions). So when when comparing two spans that differ only in their slots
// (sub-positions) the main position could still exhibit agreement.
sortedFeatures.removeIf(f -> adapter.getLinkFeature(f) != null);
}
for (String feature : sortedFeatures) {
Feature f1 = type1.getFeatureByBaseName(feature);
Feature f2 = type2.getFeatureByBaseName(feature);
switch(f1.getRange().getName()) {
case CAS.TYPE_NAME_BOOLEAN:
if (aFS1.getBooleanValue(f1) != aFS2.getBooleanValue(f2)) {
return false;
}
break;
case CAS.TYPE_NAME_BYTE:
if (aFS1.getByteValue(f1) != aFS2.getByteValue(f2)) {
return false;
}
break;
case CAS.TYPE_NAME_DOUBLE:
if (aFS1.getDoubleValue(f1) != aFS2.getDoubleValue(f2)) {
return false;
}
break;
case CAS.TYPE_NAME_FLOAT:
if (aFS1.getFloatValue(f1) != aFS2.getFloatValue(f2)) {
return false;
}
break;
case CAS.TYPE_NAME_INTEGER:
if (aFS1.getIntValue(f1) != aFS2.getIntValue(f2)) {
return false;
}
break;
case CAS.TYPE_NAME_LONG:
if (aFS1.getLongValue(f1) != aFS2.getLongValue(f2)) {
return false;
}
break;
case CAS.TYPE_NAME_SHORT:
if (aFS1.getShortValue(f1) != aFS2.getShortValue(f2)) {
return false;
}
break;
case CAS.TYPE_NAME_STRING:
if (!StringUtils.equals(aFS1.getStringValue(f1), aFS2.getStringValue(f2))) {
return false;
}
break;
default:
{
// Must be some kind of feature structure then
FeatureStructure valueFS1 = aFS1.getFeatureValue(f1);
FeatureStructure valueFS2 = aFS2.getFeatureValue(f2);
// Ignore the SofaFS - we already checked that the CAS is the same.
if (valueFS1 instanceof SofaFS) {
continue;
}
// If the feature value is an annotation, we just check the position is the same,
// but we do not go in deeper. If we we wanted to know differences on this type,
// then it should have been added as an entry type.
//
// Q: Why do we not check if they are the same based on the CAS address?
// A: Because we are checking across CASes and addresses can differ.
//
// Q: Why do we not check recursively?
// A: Because e.g. for chains, this would mean we consider the whole chain as a
// single annotation, but we want to consider each link as an annotation
TypeSystem ts1 = aFS1.getCAS().getTypeSystem();
if (ts1.subsumes(ts1.getType(CAS.TYPE_NAME_ANNOTATION), type1)) {
if (!equalsAnnotationFS((AnnotationFS) aFS1, (AnnotationFS) aFS2)) {
return false;
}
}
// just dealing with structured features. It is ok to check these deeply.
if (!equalsFS(valueFS1, valueFS2)) {
return false;
}
}
}
}
return true;
}
Aggregations