// arguments
List<BinaryTextRelation> relations = Lists.newArrayList();
for (BinaryTextRelation relation : goldBinaryTextRelations) {
boolean hasSystemArgs = true;
for (RelationArgument relArg : Lists.newArrayList(relation.getArg1(), relation.getArg2())) {
IdentifiedAnnotation goldArg = (IdentifiedAnnotation) relArg.getArgument();
Class<? extends IdentifiedAnnotation> goldClass = goldArg.getClass();
boolean noSystemArg = JCasUtil.selectCovered(jCas, goldClass, goldArg).isEmpty();
hasSystemArgs = hasSystemArgs && !noSystemArg;
}
if (hasSystemArgs) {
relations.add(relation);
} else {
IdentifiedAnnotation arg1 = (IdentifiedAnnotation) relation.getArg1().getArgument();
IdentifiedAnnotation arg2 = (IdentifiedAnnotation) relation.getArg2().getArgument();
String messageFormat =
"removing relation between %s and %s which is impossible to "
+ "find with system mentions";
String message = String.format(messageFormat, format(arg1), format(arg2));
UIMAFramework.getLogger(this.getClass()).log(Level.WARNING, message);
}
}
goldBinaryTextRelations = relations;
}
if (this.allowSmallerSystemArguments) {
// collect all the arguments of the manually annotated relations
Set<IdentifiedAnnotation> goldArgs = Sets.newHashSet();
for (BinaryTextRelation relation : goldBinaryTextRelations) {
for (RelationArgument relArg : Lists.newArrayList(relation.getArg1(), relation.getArg2())) {
goldArgs.add((IdentifiedAnnotation) relArg.getArgument());
}
}
// collect all the arguments of system-predicted relations that don't
// match some gold argument
Set<IdentifiedAnnotation> unmatchedSystemArgs = Sets.newHashSet();
for (BinaryTextRelation relation : systemBinaryTextRelations) {
for (RelationArgument relArg : Lists.newArrayList(relation.getArg1(), relation.getArg2())) {
IdentifiedAnnotation systemArg = (IdentifiedAnnotation) relArg.getArgument();
Class<? extends IdentifiedAnnotation> systemClass = systemArg.getClass();
boolean matchesSomeGold = false;
for (IdentifiedAnnotation goldArg : JCasUtil.selectCovered(
goldView,
systemClass,
systemArg)) {
if (goldArg.getBegin() == systemArg.getBegin()
&& goldArg.getEnd() == systemArg.getEnd()) {
matchesSomeGold = true;
break;
}
}
if (!matchesSomeGold) {
unmatchedSystemArgs.add(systemArg);
}
}
}
// map each unmatched system argument to the gold argument that encloses
// it
Map<IdentifiedAnnotation, IdentifiedAnnotation> systemToGold = Maps.newHashMap();
for (IdentifiedAnnotation goldArg : goldArgs) {
Class<? extends IdentifiedAnnotation> goldClass = goldArg.getClass();
for (IdentifiedAnnotation systemArg : JCasUtil.selectCovered(jCas, goldClass, goldArg)) {
if (unmatchedSystemArgs.contains(systemArg)) {
// if there's no mapping yet for this system arg, map it to the
// enclosing gold arg
IdentifiedAnnotation oldGoldArg = systemToGold.get(systemArg);
if (oldGoldArg == null) {
systemToGold.put(systemArg, goldArg);
}
// if there's already a mapping for this system arg, only re-map
// it to match the type
else {
IdentifiedAnnotation current, other;
if (systemArg.getTypeID() == goldArg.getTypeID()) {
systemToGold.put(systemArg, goldArg);
current = goldArg;
other = oldGoldArg;
} else {
current = oldGoldArg;
other = goldArg;
}
// issue a warning since this re-mapping procedure is imperfect
String message =
"system argument %s mapped to gold argument %s, but could also be mapped to %s";
message = String.format(message, format(systemArg), format(current), format(other));
UIMAFramework.getLogger(this.getClass()).log(Level.WARNING, message);
}
}
}
}
// replace system arguments with gold arguments where necessary/possible
for (BinaryTextRelation relation : systemBinaryTextRelations) {
for (RelationArgument relArg : Lists.newArrayList(relation.getArg1(), relation.getArg2())) {
IdentifiedAnnotation systemArg = (IdentifiedAnnotation) relArg.getArgument();
IdentifiedAnnotation matchingGoldArg = systemToGold.get(systemArg);
if (matchingGoldArg != null) {
String messageFormat = "replacing system argument %s with gold argument %s";
String message =
String.format(messageFormat, format(systemArg), format(matchingGoldArg));
UIMAFramework.getLogger(this.getClass()).log(Level.WARNING, message);