use of org.corpus_tools.salt.core.SRelation in project ANNIS by korpling.
the class SaltAnnotateExtractor method createMissingSpanningRelations.
/**
* Use the left/right token index of the spans to create spanning relations
* when this did not happen yet.
*
* @param graph
* @param nodeByRankID
* @param numberOfRelations
*/
private void createMissingSpanningRelations(SDocumentGraph graph, FastInverseMap<Long, SNode> nodeByRankID, TreeMap<Long, SToken> tokenByIndex, Map<String, ComponentEntry> componentForSpan, AtomicInteger numberOfRelations) {
// add the missing spanning relations for each continuous span of the graph
for (SSpan span : graph.getSpans()) {
long pre = 1;
RelannisNodeFeature featSpan = RelannisNodeFeature.extract(span);
ComponentEntry spanComponent = componentForSpan.get(span.getId());
if (spanComponent != null && featSpan != null && featSpan.getLeftToken() >= 0 && featSpan.getRightToken() >= 0) {
for (long i = featSpan.getLeftToken(); i <= featSpan.getRightToken(); i++) {
SToken tok = tokenByIndex.get(i);
if (tok != null) {
boolean missing = true;
List<SRelation<SNode, SNode>> existingRelations = graph.getRelations(span.getId(), tok.getId());
if (existingRelations != null) {
for (Relation e : existingRelations) {
if (e instanceof SSpanningRelation) {
missing = false;
break;
}
}
}
if (missing) {
String type = "c";
SLayer layer = findOrAddSLayer(spanComponent.getNamespace(), graph);
createNewRelation(graph, span, tok, null, type, spanComponent.getId(), layer, pre++, nodeByRankID, numberOfRelations);
}
}
// end if token exists
}
// end for each covered token index
}
}
// end for each span
}
use of org.corpus_tools.salt.core.SRelation in project ANNIS by korpling.
the class TimelineReconstructor method moveRelations.
private void moveRelations(SStructuredNode oldSpan, SToken newToken, Set<String> validSpanAnnos, String orderName) {
final List<SRelation> inRels = new LinkedList<>(oldSpan.getInRelations());
final List<SRelation> outRels = new LinkedList<>(oldSpan.getOutRelations());
final List<SToken> coveredByOldSpan = new LinkedList<>();
for (SRelation rel : outRels) {
if (rel instanceof SPointingRelation || rel instanceof SDominanceRelation) {
rel.setSource(newToken);
} else if (rel instanceof SSpanningRelation) {
coveredByOldSpan.add(((SSpanningRelation) rel).getTarget());
}
}
for (SRelation rel : inRels) {
if (rel instanceof SPointingRelation || rel instanceof SDominanceRelation) {
rel.setTarget(newToken);
}
}
// find the connected spans and connect them with the new token instead
for (SToken tok : coveredByOldSpan) {
if (tok.getInRelations() != null) {
for (SRelation<?, ?> rel : tok.getInRelations()) {
if (rel instanceof SSpanningRelation) {
boolean valid = false;
SSpan spanToMap = ((SSpanningRelation) rel).getSource();
if (virtualTokenizationFromNamespace) {
for (SAnnotation anno : spanToMap.getAnnotations()) {
if (anno.getNamespace() != null && anno.getNamespace().equals(orderName)) {
valid = true;
break;
}
}
} else {
for (String validAnno : validSpanAnnos) {
if (spanToMap.getAnnotation(validAnno) != null) {
valid = true;
break;
}
}
}
if (valid) {
graph.createRelation(spanToMap, newToken, SALT_TYPE.SSPANNING_RELATION, null);
}
}
}
}
}
}
use of org.corpus_tools.salt.core.SRelation in project ANNIS by korpling.
the class TimelineReconstructor method createTokenFromSOrder.
private void createTokenFromSOrder() {
nodesToDelete.add(graph.getTextualDSs().get(0));
Map<String, SSpan> rootNodes = new HashMap<>();
// also add nodes that are are marked as start by ANNIS even if they don't have an outgoing order rel
for (SSpan n : graph.getSpans()) {
SFeature feat = n.getFeature(AnnisConstants.ANNIS_NS, AnnisConstants.FEAT_FIRST_NODE_SEGMENTATION_CHAIN);
if (feat != null && feat.getValue_STEXT() != null) {
rootNodes.put(feat.getValue_STEXT(), n);
} else {
// check if there is no incoming SOrderRelation but an outgoing
boolean isRoot = true;
for (SRelation<?, ?> inRel : n.getInRelations()) {
if (inRel instanceof SOrderRelation) {
isRoot = false;
break;
}
}
if (isRoot) {
for (SRelation<?, ?> outRel : n.getOutRelations()) {
if (outRel instanceof SOrderRelation) {
rootNodes.put(((SOrderRelation) outRel).getType(), n);
break;
}
}
}
}
}
// convert all root nodes to spans
for (Map.Entry<String, SSpan> rootEntry : rootNodes.entrySet()) {
SNode root = rootEntry.getValue();
String orderName = rootEntry.getKey();
convertSpanToToken((SSpan) root, orderName);
}
// traverse through all SOrderRelations in order
graph.traverse(new LinkedList<SNode>(rootNodes.values()), GRAPH_TRAVERSE_TYPE.TOP_DOWN_DEPTH_FIRST, "TimeReconstructSOrderRelations", new GraphTraverseHandler() {
@Override
public void nodeReached(GRAPH_TRAVERSE_TYPE traversalType, String traversalId, SNode currNode, SRelation relation, SNode fromNode, long order) {
if (relation instanceof SOrderRelation && currNode instanceof SSpan) {
String orderName = ((SOrderRelation) relation).getType();
if (fromNode != null) {
// add a space to the text
StringBuilder t = textDataByName.get(orderName);
if (t != null) {
t.append(" ");
}
}
convertSpanToToken((SSpan) currNode, orderName);
}
}
@Override
public void nodeLeft(GRAPH_TRAVERSE_TYPE traversalType, String traversalId, SNode currNode, SRelation relation, SNode fromNode, long order) {
}
@Override
public boolean checkConstraint(GRAPH_TRAVERSE_TYPE traversalType, String traversalId, SRelation relation, SNode currNode, long order) {
if (relation == null || relation instanceof SOrderRelation) {
return true;
} else {
return false;
}
}
});
// update the text of the TextualDSs
for (Map.Entry<String, StringBuilder> textDataEntry : textDataByName.entrySet()) {
STextualDS textDS = textsByName.get(textDataEntry.getKey());
if (textDS != null) {
textDS.setText(textDataEntry.getValue().toString());
}
}
}
use of org.corpus_tools.salt.core.SRelation in project ANNIS by korpling.
the class TimeHelper method getOverlappedTime.
/**
* Get start and end time from the overlapped {@link SToken}. The minimum
* start time and maximum end times are choosen.
* @param node The span to start from.
* @return A double array, will have length of 0 if no time annotations where found,
* one element of only start elements where found, 2 elements if both
* start and end time are found.
*/
public static double[] getOverlappedTime(SNode node) {
SGraph graph = node.getGraph();
final List<Double> startTimes = new LinkedList<>();
final List<Double> endTimes = new LinkedList<>();
List<SToken> token = new LinkedList<>();
if (node instanceof SToken) {
token.add((SToken) node);
} else {
List<SRelation<SNode, SNode>> outRelations = graph.getOutRelations(node.getId());
if (outRelations != null) {
for (SRelation<? extends SNode, ? extends SNode> e : outRelations) {
if (e instanceof SSpanningRelation) {
SToken tok = ((SSpanningRelation) e).getTarget();
token.add(tok);
}
}
}
// end for each out relations
}
for (SToken tok : token) {
SAnnotation anno = tok.getAnnotation(SaltUtil.createQName("annis", "time"));
if (anno != null && anno.getValue_STEXT() != null && !anno.getValue_STEXT().isEmpty() && !anno.getValue_STEXT().matches("\\-[0-9]*(\\.[0-9]*)?")) {
try {
String[] split = anno.getValue_STEXT().split("-");
if (split.length == 1) {
startTimes.add(Double.parseDouble(split[0]));
}
if (split.length == 2) {
startTimes.add(Double.parseDouble(split[0]));
endTimes.add(Double.parseDouble(split[1]));
}
} catch (NumberFormatException ex) {
log.debug("Invalid time annotation", ex);
}
}
}
if (startTimes.size() > 0 && endTimes.size() > 0) {
return new double[] { Collections.min(startTimes), Collections.max(endTimes) };
} else if (startTimes.size() > 0) {
return new double[] { Collections.min(startTimes) };
}
return new double[0];
}
Aggregations