use of annis.model.RelannisNodeFeature in project ANNIS by korpling.
the class LegacyGraphConverter method convertToAnnotationGraph.
public static AnnotationGraph convertToAnnotationGraph(SDocument document) {
SDocumentGraph docGraph = document.getDocumentGraph();
SFeature featMatchedIDs = docGraph.getFeature(ANNIS_NS, FEAT_MATCHEDIDS);
Match match = new Match();
if (featMatchedIDs != null && featMatchedIDs.getValue_STEXT() != null) {
match = Match.parseFromString(featMatchedIDs.getValue_STEXT(), ',');
}
// get matched node names by using the IDs
List<Long> matchedNodeIDs = new ArrayList<>();
for (URI u : match.getSaltIDs()) {
SNode node = docGraph.getNode(u.toASCIIString());
if (node == null) {
// that's weird, fallback to the id
log.warn("Could not get matched node from id {}", u.toASCIIString());
matchedNodeIDs.add(-1l);
} else {
RelannisNodeFeature relANNISFeat = (RelannisNodeFeature) node.getFeature(SaltUtil.createQName(ANNIS_NS, FEAT_RELANNIS_NODE)).getValue();
matchedNodeIDs.add(relANNISFeat.getInternalID());
}
}
AnnotationGraph result = convertToAnnotationGraph(docGraph, matchedNodeIDs);
return result;
}
use of annis.model.RelannisNodeFeature in project ANNIS by korpling.
the class LegacyGraphConverter method convertToAnnotationGraph.
public static AnnotationGraph convertToAnnotationGraph(SDocumentGraph docGraph, List<Long> matchedNodeIDs) {
Set<Long> matchSet = new HashSet<>(matchedNodeIDs);
AnnotationGraph annoGraph = new AnnotationGraph();
List<String> pathList = CommonHelper.getCorpusPath(docGraph.getDocument().getGraph(), docGraph.getDocument());
annoGraph.setPath(pathList.toArray(new String[pathList.size()]));
annoGraph.setDocumentName(docGraph.getDocument().getName());
Map<SNode, AnnisNode> allNodes = new HashMap<>();
for (SNode sNode : docGraph.getNodes()) {
SFeature featNodeRaw = sNode.getFeature(SaltUtil.createQName(ANNIS_NS, FEAT_RELANNIS_NODE));
if (featNodeRaw != null) {
RelannisNodeFeature featNode = (RelannisNodeFeature) featNodeRaw.getValue();
long internalID = featNode.getInternalID();
AnnisNode aNode = new AnnisNode(internalID);
for (SAnnotation sAnno : sNode.getAnnotations()) {
aNode.addNodeAnnotation(new Annotation(sAnno.getNamespace(), sAnno.getName(), sAnno.getValue_STEXT()));
}
aNode.setName(sNode.getName());
Set<SLayer> layers = sNode.getLayers();
if (!layers.isEmpty()) {
aNode.setNamespace(layers.iterator().next().getName());
}
RelannisNodeFeature feat = (RelannisNodeFeature) sNode.getFeature(SaltUtil.createQName(ANNIS_NS, FEAT_RELANNIS_NODE)).getValue();
if (sNode instanceof SToken) {
List<DataSourceSequence> seqList = docGraph.getOverlappedDataSourceSequence(sNode, SALT_TYPE.STEXT_OVERLAPPING_RELATION);
if (seqList != null) {
DataSourceSequence seq = seqList.get(0);
Preconditions.checkNotNull(seq, "DataSourceSequence is null for token %s", sNode.getId());
SSequentialDS seqDS = seq.getDataSource();
Preconditions.checkNotNull(seqDS, "SSequentalDS is null for token %s", sNode.getId());
Preconditions.checkNotNull(seqDS.getData(), "SSequentalDS data is null for token %s", sNode.getId());
String seqDSData = (String) seqDS.getData();
Preconditions.checkNotNull(seqDSData, "casted SSequentalDS data is null for token %s", sNode.getId());
Preconditions.checkNotNull(seq.getStart(), "SSequentalDS start is null for token %s", sNode.getId());
Preconditions.checkNotNull(seq.getEnd(), "SSequentalDS end is null for supposed token %s", sNode.getId());
int start = seq.getStart().intValue();
int end = seq.getEnd().intValue();
Preconditions.checkState(start >= 0 && start <= end && end <= seqDSData.length(), "Illegal start or end of textual DS for token (start %s, end: %s)", sNode.getId(), start, end);
String spannedText = seqDSData.substring(start, end);
Preconditions.checkNotNull(spannedText, "spanned text is null for supposed token %s (start: %s, end: %s)", sNode.getId(), start, end);
aNode.setSpannedText(spannedText);
aNode.setToken(true);
aNode.setTokenIndex(feat.getTokenIndex());
}
} else {
aNode.setToken(false);
aNode.setTokenIndex(null);
}
aNode.setCorpus(feat.getCorpusRef());
aNode.setTextId(feat.getTextRef());
aNode.setLeft(feat.getLeft());
aNode.setLeftToken(feat.getLeftToken());
aNode.setRight(feat.getRight());
aNode.setRightToken(feat.getRightToken());
if (matchSet.contains(aNode.getId())) {
aNode.setMatchedNodeInQuery((long) matchedNodeIDs.indexOf(aNode.getId()) + 1);
annoGraph.getMatchedNodeIds().add(aNode.getId());
} else {
aNode.setMatchedNodeInQuery(null);
}
annoGraph.addNode(aNode);
allNodes.put(sNode, aNode);
}
}
for (SRelation rel : docGraph.getRelations()) {
RelannisEdgeFeature featRelation = RelannisEdgeFeature.extract(rel);
if (featRelation != null) {
addRelation(rel, featRelation.getPre(), featRelation.getComponentID(), allNodes, annoGraph);
}
}
// add relations with empty relation name for every dominance relation
List<SDominanceRelation> dominanceRelations = new LinkedList<>(docGraph.getDominanceRelations());
for (SDominanceRelation rel : dominanceRelations) {
RelannisEdgeFeature featEdge = RelannisEdgeFeature.extract(rel);
if (featEdge != null && featEdge.getArtificialDominanceComponent() != null && featEdge.getArtificialDominancePre() != null) {
addRelation(SDominanceRelation.class, null, rel.getAnnotations(), rel.getSource(), rel.getTarget(), rel.getLayers(), featEdge.getArtificialDominancePre(), featEdge.getArtificialDominanceComponent(), allNodes, annoGraph);
}
}
return annoGraph;
}
use of annis.model.RelannisNodeFeature in project ANNIS by korpling.
the class EventExtractor method splitRowsOnGaps.
/**
* Splits events of a row if they contain a gap. Gaps are found using the
* token index (provided as ANNIS specific {@link SFeature}. Inserted events
* have a special style to mark them as gaps.
*
* @param row
* @param graph
* @param startTokenIndex token index of the first token in the match
* @param endTokenIndex token index of the last token in the match
*/
private static void splitRowsOnGaps(Row row, final SDocumentGraph graph, long startTokenIndex, long endTokenIndex) {
ListIterator<GridEvent> itEvents = row.getEvents().listIterator();
while (itEvents.hasNext()) {
GridEvent event = itEvents.next();
int lastTokenIndex = -1;
// sort the coveredIDs
LinkedList<String> sortedCoveredToken = new LinkedList<>(event.getCoveredIDs());
Collections.sort(sortedCoveredToken, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
SNode node1 = graph.getNode(o1);
SNode node2 = graph.getNode(o2);
if (node1 == node2) {
return 0;
}
if (node1 == null) {
return -1;
}
if (node2 == null) {
return +1;
}
RelannisNodeFeature feat1 = (RelannisNodeFeature) node1.getFeature(ANNIS_NS, FEAT_RELANNIS_NODE).getValue();
RelannisNodeFeature feat2 = (RelannisNodeFeature) node2.getFeature(ANNIS_NS, FEAT_RELANNIS_NODE).getValue();
long tokenIndex1 = feat1.getTokenIndex();
long tokenIndex2 = feat2.getTokenIndex();
return ((Long) (tokenIndex1)).compareTo(tokenIndex2);
}
});
// first calculate all gaps
List<GridEvent> gaps = new LinkedList<>();
for (String id : sortedCoveredToken) {
SNode node = graph.getNode(id);
RelannisNodeFeature feat = (RelannisNodeFeature) node.getFeature(ANNIS_NS, FEAT_RELANNIS_NODE).getValue();
long tokenIndexRaw = feat.getTokenIndex();
tokenIndexRaw = clip(tokenIndexRaw, startTokenIndex, endTokenIndex);
int tokenIndex = (int) (tokenIndexRaw - startTokenIndex);
// sanity check
if (tokenIndex >= event.getLeft() && tokenIndex <= event.getRight()) {
int diff = tokenIndex - lastTokenIndex;
if (lastTokenIndex >= 0 && diff > 1) {
// we detected a gap
GridEvent gap = new GridEvent(event.getId() + "_gap_" + gaps.size(), lastTokenIndex + 1, tokenIndex - 1, "");
gap.setGap(true);
gaps.add(gap);
}
lastTokenIndex = tokenIndex;
} else {
// reset gap search when discovered there were token we use for
// hightlighting but do not actually cover
lastTokenIndex = -1;
}
}
// end for each covered token id
ListIterator<GridEvent> itGaps = gaps.listIterator();
// remember the old right value
int oldRight = event.getRight();
int gapNr = 0;
while (itGaps.hasNext()) {
GridEvent gap = itGaps.next();
if (gapNr == 0) {
// shorten original event
event.setRight(gap.getLeft() - 1);
}
// insert the real gap
itEvents.add(gap);
int rightBorder = oldRight;
if (itGaps.hasNext()) {
// don't use the old event right border since the gap should only go until
// the next event
GridEvent nextGap = itGaps.next();
itGaps.previous();
rightBorder = nextGap.getLeft() - 1;
}
// insert a new event node that covers the rest of the event
GridEvent after = new GridEvent(event);
after.setId(event.getId() + "_after_" + gapNr);
after.setLeft(gap.getRight() + 1);
after.setRight(rightBorder);
itEvents.add(after);
gapNr++;
}
}
}
use of annis.model.RelannisNodeFeature in project ANNIS by korpling.
the class GridComponent method computeTokenRow.
private Row computeTokenRow(List<SNode> tokens, SDocumentGraph graph, LinkedHashMap<String, ArrayList<Row>> rowsByAnnotation, long startIndex, AtomicInteger tokenOffsetForText) {
/* we will only add tokens of one texts which is mentioned by any
included annotation. */
Set<String> validTextIDs = new HashSet<>();
if (enforcedText == null) {
Iterator<ArrayList<Row>> itAllRows = rowsByAnnotation.values().iterator();
while (itAllRows.hasNext()) {
ArrayList<Row> rowsForAnnotation = itAllRows.next();
for (Row r : rowsForAnnotation) {
validTextIDs.addAll(r.getTextIDs());
}
}
/**
* we want to show all token if no valid text was found and we have only one
* text and the first one if there are more than one text.
*/
List<STextualDS> allTexts = graph.getTextualDSs();
if (validTextIDs.isEmpty() && allTexts != null && (allTexts.size() == 1 || allTexts.size() == 2)) {
validTextIDs.add(allTexts.get(0).getId());
}
} else {
validTextIDs.add(enforcedText.getId());
}
Row tokenRow = new Row();
for (SNode t : tokens) {
// get the Salt ID of the STextualDS of this token
STextualDS tokenText = CommonHelper.getTextualDSForNode(t, graph);
// only add token if text ID matches the valid one
if (tokenText != null && validTextIDs.contains(tokenText.getId())) {
RelannisNodeFeature feat = (RelannisNodeFeature) t.getFeature(AnnisConstants.ANNIS_NS, AnnisConstants.FEAT_RELANNIS_NODE).getValue();
long idxLeft = feat.getLeftToken() - startIndex;
long idxRight = feat.getRightToken() - startIndex;
if (tokenOffsetForText.get() < 0) {
// set the token offset by assuming the first idx must be zero
tokenOffsetForText.set(Math.abs((int) idxLeft));
}
String text = extractTextForToken(t, segmentationName);
GridEvent event = new GridEvent(t.getId(), (int) idxLeft, (int) idxRight, text);
event.setTextID(tokenText.getId());
// check if the token is a matched node
Long match = isCoveredTokenMarked() ? markCoveredTokens(input.getMarkedAndCovered(), t) : tokenMatch(t);
event.setMatch(match);
tokenRow.addEvent(event);
}
}
return tokenRow;
}
use of annis.model.RelannisNodeFeature in project ANNIS by korpling.
the class GridComponent method createAnnotationGrid.
private void createAnnotationGrid() {
String resultID = input.getId();
grid = new AnnotationGrid(mediaController, pdfController, resultID);
grid.addStyleName(getMainStyle());
grid.addStyleName(Helper.CORPUS_FONT_FORCE);
grid.setEscapeHTML(Boolean.parseBoolean(input.getMappings().getProperty(MAPPING_ESCAPE_HTML, "true")));
LinkedList<Class<? extends SNode>> types = new LinkedList<>();
if (isShowingSpanAnnotations()) {
types.add(SSpan.class);
}
if (isShowingTokenAnnotations()) {
types.add(SToken.class);
}
grid.setAnnosWithNamespace(EventExtractor.computeDisplayedNamespace(input, types));
layout.addComponent(grid);
SDocumentGraph graph = input.getDocument().getDocumentGraph();
List<SNode> tokens = CommonHelper.getSortedSegmentationNodes(segmentationName, graph);
Preconditions.checkArgument(!tokens.isEmpty(), "Token list must be non-empty");
RelannisNodeFeature featTokStart = (RelannisNodeFeature) tokens.get(0).getFeature(AnnisConstants.ANNIS_NS, AnnisConstants.FEAT_RELANNIS_NODE).getValue();
long startIndex = featTokStart.getTokenIndex();
RelannisNodeFeature featTokEnd = (RelannisNodeFeature) tokens.get(tokens.size() - 1).getFeature(AnnisConstants.ANNIS_NS, AnnisConstants.FEAT_RELANNIS_NODE).getValue();
long endIndex = featTokEnd.getTokenIndex();
LinkedHashMap<String, ArrayList<Row>> rowsByAnnotation = computeAnnotationRows(startIndex, endIndex);
// Get Mappings
String gridTemplates = input.getMappings().getProperty(MAPPING_GRID_TEMPLATES, "");
// Parse Mappings
if (!gridTemplates.equals("")) {
String[] split = gridTemplates.split("\\|\\|");
for (String s : split) {
// example of s: entity="person"==>:), or infstat==><b>%%value%%</b>
String[] unit_split = s.split("==>");
Set set = rowsByAnnotation.entrySet();
// Displaying elements of LinkedHashMap
Iterator iterator = set.iterator();
while (iterator.hasNext()) {
// iterate over rows
Map.Entry me = (Map.Entry) iterator.next();
String rowKey = (String) me.getKey();
ArrayList<Row> rowValue = (ArrayList<Row>) me.getValue();
for (Row rowValue1 : rowValue) {
ArrayList<GridEvent> rowEvents = rowValue1.getEvents();
if (unit_split[0].indexOf('=') < 0) {
// unit_split[0] is a single instruction, e.g., infstat
// check if the key of a row in rowsByAnnotation is unit_split[0]
// if it is, we need to change every value of this row, else we dont do anything
String rowName = rowKey.split("::")[1];
if (rowName.equals(unit_split[0])) {
// iterate over all values and replace the value with the unit_split[1]
for (GridEvent ev : rowEvents) {
String origValue = ev.getValue();
String newValue = unit_split[1].replaceAll("%%value%%", origValue);
ev.setValue(newValue);
}
}
} else {
// its a instruction like entity='person'
// first break this split into entity and person
// check if rowKey is entity, then when iterating over events, check if value is person
String rowName = rowKey.split("::")[1];
String targetRow = unit_split[0].split("=")[0];
String targetValue = unit_split[0].split("=")[1].replaceAll("\"", "");
if (rowName.equals(targetRow)) {
// iterate over all values and replace the value with the unit_split[1]
for (GridEvent ev : rowEvents) {
String origValue = ev.getValue();
if (origValue.equals(targetValue)) {
ev.setValue(unit_split[1]);
}
// String newValue = unit_split[1].replaceAll("%%value%%",origValue);
}
}
}
}
}
}
}
// add tokens as row
AtomicInteger tokenOffsetForText = new AtomicInteger(-1);
Row tokenRow = computeTokenRow(tokens, graph, rowsByAnnotation, startIndex, tokenOffsetForText);
if (isHidingToken()) {
tokenRow.setStyle("invisible_token");
}
if (isTokenFirst()) {
// copy original list but add token row at the beginning
LinkedHashMap<String, ArrayList<Row>> newList = new LinkedHashMap<>();
newList.put("tok", Lists.newArrayList(tokenRow));
newList.putAll(rowsByAnnotation);
rowsByAnnotation = newList;
} else {
// just add the token row to the end of the list
rowsByAnnotation.put("tok", Lists.newArrayList(tokenRow));
}
EventExtractor.removeEmptySpace(rowsByAnnotation, tokenRow);
// check if the token row only contains empty values
boolean tokenRowIsEmpty = true;
for (GridEvent tokenEvent : tokenRow.getEvents()) {
if (tokenEvent.getValue() != null && !tokenEvent.getValue().trim().isEmpty()) {
tokenRowIsEmpty = false;
break;
}
}
if (!isHidingToken() && canShowEmptyTokenWarning()) {
lblEmptyToken.setVisible(tokenRowIsEmpty);
}
grid.setRowsByAnnotation(rowsByAnnotation);
grid.setTokenIndexOffset(tokenOffsetForText.get());
}
Aggregations