Skip to content

Commit

Permalink
Merge pull request #4837 from inception-project/feature/4809-Connecti…
Browse files Browse the repository at this point in the history
…ng-annotation-and-entity-with-arc-over-different-pages

#4809 - Connecting annotation and entity with arc over different pages
  • Loading branch information
reckart authored May 30, 2024
2 parents ab12e22 + 9dc521b commit 73a1f2a
Show file tree
Hide file tree
Showing 26 changed files with 233 additions and 180 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,14 @@ protected boolean typeSystemInit(TypeSystem aTypeSystem)

@Override
public void render(RenderRequest aRequest, List<AnnotationFeature> aFeatures,
VDocument aResponse, int windowBeginOffset, int windowEndOffset)
VDocument aResponse)
{
// Nothing to do
}

@Override
public List<VObject> render(RenderRequest aRequest, List<AnnotationFeature> aFeatures,
VDocument aResponse, int windowBeginOffset, int windowEndOffset, AnnotationFS aFS)
VDocument aResponse, AnnotationFS aFS)

{
return Collections.emptyList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,7 @@ public void render(VDocument aResponse, RenderRequest aRequest)
var renderBegin = Math.max(0, aRequest.getWindowBeginOffset());
var renderEnd = Math.min(documentText.length(), aRequest.getWindowEndOffset());
aResponse.setText(documentText.substring(renderBegin, renderEnd));
aResponse.setWindowBegin(renderBegin);
aResponse.setWindowEnd(renderEnd);
aResponse.setWindow(renderBegin, renderEnd);

var start = System.currentTimeMillis();
var project = aRequest.getProject();
Expand All @@ -129,7 +128,7 @@ public void render(VDocument aResponse, RenderRequest aRequest)
// the same because otherwise the IDs of armed slots would be inconsistent
LayerSupport<?, ?> layerSupport = layerSupportRegistry.getLayerSupport(layer);
var renderer = layerSupport.createRenderer(layer, () -> layerAllFeatures);
renderer.render(aRequest, layerSupportedFeatures, aResponse, renderBegin, renderEnd);
renderer.render(aRequest, layerSupportedFeatures, aResponse);
}

if (LOG.isTraceEnabled()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public List<AnnotationFS> selectAnnotationsInWindow(CAS aCas, int aWindowBegin,

@Override
public void render(RenderRequest aRequest, List<AnnotationFeature> aFeatures,
VDocument aResponse, int aWindowBegin, int aWindowEnd)
VDocument aResponse)
{
if (!checkTypeSystem(aRequest.getCas())) {
return;
Expand All @@ -125,7 +125,10 @@ public void render(RenderRequest aRequest, List<AnnotationFeature> aFeatures,
// Sorted index mapping annotations to the corresponding rendered spans
var annoToSpanIdx = new HashMap<AnnotationFS, VSpan>();

int colorIndex = 0;
var windowBegin = aResponse.getWindowBegin();
var windowEnd = aResponse.getWindowEnd();

var colorIndex = 0;
// Iterate over the chains
var chains = aRequest.getCas().select(typeAdapter.getChainTypeName()).asList();
for (var chainFs : chains) {
Expand All @@ -139,13 +142,13 @@ public void render(RenderRequest aRequest, List<AnnotationFeature> aFeatures,
var nextLinkFs = (AnnotationFS) linkFs.getFeatureValue(linkNext);

// Is link after window? If yes, we can skip the rest of the chain
if (linkFs.getBegin() >= aWindowEnd) {
if (linkFs.getBegin() >= windowBegin) {
break; // Go to next chain
}

// Is not overlapping the viewport? We only need links that are actually visible in
// the viewport
if (!overlapping(linkFs, aWindowBegin, aWindowEnd)) {
if (!overlapping(linkFs, windowBegin, windowEnd)) {
// prevLinkFs remains null until we enter the window
linkFs = nextLinkFs;
continue; // Go to next link
Expand Down Expand Up @@ -201,13 +204,13 @@ public void render(RenderRequest aRequest, List<AnnotationFeature> aFeatures,
}

for (var behavior : behaviors) {
behavior.onRender(typeAdapter, aResponse, annoToSpanIdx, aWindowBegin, aWindowEnd);
behavior.onRender(typeAdapter, aResponse, annoToSpanIdx);
}
}

@Override
public List<VObject> render(RenderRequest aRequest, List<AnnotationFeature> aFeatures,
VDocument aResponse, int windowBeginOffset, int windowEndOffset, AnnotationFS aFS)
VDocument aResponse, AnnotationFS aFS)
{
return Collections.emptyList();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
import de.tudarmstadt.ukp.inception.rendering.vmodel.VObject;
import de.tudarmstadt.ukp.inception.rendering.vmodel.VRange;
import de.tudarmstadt.ukp.inception.rendering.vmodel.VSpan;
import de.tudarmstadt.ukp.inception.schema.api.adapter.TypeAdapter;
import de.tudarmstadt.ukp.inception.schema.api.feature.FeatureSupportRegistry;
import de.tudarmstadt.ukp.inception.schema.api.layer.LayerSupportRegistry;
import de.tudarmstadt.ukp.inception.support.uima.ICasUtil;
Expand All @@ -70,13 +71,13 @@ public class RelationRenderer
{
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

private static final VID VID_BEFORE = VID.builder() //
public static final VID VID_BEFORE = VID.builder() //
.withExtensionId("rel") //
.withAnnotationId(0) //
.withExtensionPayload("before") //
.build();

private static final VID VID_AFTER = VID.builder() //
public static final VID VID_AFTER = VID.builder() //
.withExtensionId("rel") //
.withAnnotationId(1) //
.withExtensionPayload("after") //
Expand Down Expand Up @@ -136,7 +137,7 @@ private List<Annotation> selectAnnotationsInWindow(RenderRequest aRequest, int a
{
var cas = aRequest.getCas();

if (!aRequest.isOutOfRangeRelations()) {
if (!aRequest.isLongArcs()) {
return cas.<Annotation> select(type).coveredBy(aWindowBegin, aWindowEnd).toList();
}

Expand All @@ -160,7 +161,7 @@ private List<Annotation> selectAnnotationsInWindow(RenderRequest aRequest, int a

@Override
public void render(RenderRequest aRequest, List<AnnotationFeature> aFeatures,
VDocument aResponse, int aWindowBegin, int aWindowEnd)
VDocument aResponse)
{
if (!checkTypeSystem(aRequest.getCas())) {
return;
Expand All @@ -171,10 +172,11 @@ public void render(RenderRequest aRequest, List<AnnotationFeature> aFeatures,
// Index mapping annotations to the corresponding rendered arcs
var annoToArcIdx = new HashMap<AnnotationFS, VArc>();

var annotations = selectAnnotationsInWindow(aRequest, aWindowBegin, aWindowEnd);
var annotations = selectAnnotationsInWindow(aRequest, aResponse.getWindowBegin(),
aResponse.getWindowEnd());

for (var fs : annotations) {
for (var obj : render(aRequest, aFeatures, aResponse, aWindowBegin, aWindowEnd, fs)) {
for (var obj : render(aRequest, aFeatures, aResponse, fs)) {
if (!(obj instanceof VArc)) {
aResponse.add(obj);
continue;
Expand Down Expand Up @@ -219,7 +221,7 @@ Optional<String> renderYield(AnnotationFS fs)

@Override
public List<VObject> render(RenderRequest aRequest, List<AnnotationFeature> aFeatures,
VDocument aVDocument, int aWindowBegin, int aWindowEnd, AnnotationFS aFS)
VDocument aVDocument, AnnotationFS aFS)
{
if (!checkTypeSystem(aFS.getCAS())) {
return emptyList();
Expand Down Expand Up @@ -252,11 +254,11 @@ public List<VObject> render(RenderRequest aRequest, List<AnnotationFeature> aFea
switch (traits.getRenderMode()) {
case ALWAYS:
return renderRelationAsArcs(aRequest, aVDocument, aFS, typeAdapter, sourceFs, targetFs,
labelFeatures, aWindowBegin, aWindowEnd);
labelFeatures);
case WHEN_SELECTED:
if (aRequest.getState() == null || isSelected(aRequest, aFS, sourceFs, targetFs)) {
return renderRelationAsArcs(aRequest, aVDocument, aFS, typeAdapter, sourceFs,
targetFs, labelFeatures, aWindowBegin, aWindowEnd);
targetFs, labelFeatures);
}
return renderRelationOnLabel(aVDocument, typeAdapter, sourceFs, targetFs,
labelFeatures);
Expand All @@ -265,7 +267,7 @@ public List<VObject> render(RenderRequest aRequest, List<AnnotationFeature> aFea
labelFeatures);
default:
return renderRelationAsArcs(aRequest, aVDocument, aFS, typeAdapter, sourceFs, targetFs,
labelFeatures, aWindowBegin, aWindowEnd);
labelFeatures);
}
}

Expand Down Expand Up @@ -318,16 +320,13 @@ private List<VObject> renderRelationOnLabel(VDocument aVDocument, RelationAdapte

private List<VObject> renderRelationAsArcs(RenderRequest aRequest, VDocument aVDocument,
AnnotationFS aFS, RelationAdapter typeAdapter, FeatureStructure sourceFs,
FeatureStructure targetFs, Map<String, String> labelFeatures, int aWindowBegin,
int aWindowEnd)
FeatureStructure targetFs, Map<String, String> labelFeatures)
{
var objects = new ArrayList<VObject>();

var source = createRelationEndpoint(aRequest, aVDocument, (AnnotationFS) sourceFs,
aWindowBegin, aWindowEnd, typeAdapter);
var source = createEndpoint(aRequest, aVDocument, (AnnotationFS) sourceFs, typeAdapter);

var target = createRelationEndpoint(aRequest, aVDocument, (AnnotationFS) targetFs,
aWindowBegin, aWindowEnd, typeAdapter);
var target = createEndpoint(aRequest, aVDocument, (AnnotationFS) targetFs, typeAdapter);

objects.add(VArc.builder().forAnnotation(aFS) //
.withLayer(typeAdapter.getLayer()) //
Expand All @@ -339,11 +338,14 @@ private List<VObject> renderRelationAsArcs(RenderRequest aRequest, VDocument aVD
return objects;
}

private VID createRelationEndpoint(RenderRequest aRequest, VDocument aVDocument,
AnnotationFS aEndpoint, int aWindowBegin, int aWindowEnd, RelationAdapter aTypeAdapter)
public static VID createEndpoint(RenderRequest aRequest, VDocument aVDocument,
AnnotationFS aEndpoint, TypeAdapter aTypeAdapter)
{
if (aEndpoint.getEnd() < aWindowBegin) {
if (aRequest.isClipRelations()) {
var windowBegin = aVDocument.getWindowBegin();
var windowEnd = aVDocument.getWindowEnd();

if (aEndpoint.getEnd() < windowBegin) {
if (aRequest.isClipArcs()) {
if (aVDocument.getSpan(VID_BEFORE) == null) {
var beforeAnchor = VSpan.builder() //
.withVid(VID_BEFORE) //
Expand All @@ -357,22 +359,22 @@ private VID createRelationEndpoint(RenderRequest aRequest, VDocument aVDocument,

var placeholder = VSpan.builder() //
.forAnnotation(aEndpoint) //
.placeholder() //
.withLayer(aTypeAdapter.getLayer()) //
.withRange(new VRange(aEndpoint.getBegin() - aWindowBegin,
aEndpoint.getEnd() - aWindowBegin)) //
.withRange(new VRange(aEndpoint.getBegin() - windowBegin,
aEndpoint.getEnd() - windowBegin)) //
.build();
aVDocument.add(placeholder);
return placeholder.getVid();
}

if (aEndpoint.getBegin() >= aWindowEnd) {
if (aRequest.isClipRelations()) {
if (aEndpoint.getBegin() >= windowEnd) {
if (aRequest.isClipArcs()) {
if (aVDocument.getSpan(VID_AFTER) == null) {
var afterAnchor = VSpan.builder() //
.withVid(VID_AFTER) //
.withLayer(aTypeAdapter.getLayer()) //
.withRange(new VRange(aWindowEnd - aWindowBegin,
aWindowEnd - aWindowBegin)) //
.withRange(new VRange(windowEnd - windowBegin, windowEnd - windowBegin)) //
.build();
aVDocument.add(afterAnchor);
}
Expand All @@ -381,9 +383,10 @@ private VID createRelationEndpoint(RenderRequest aRequest, VDocument aVDocument,

var placeholder = VSpan.builder() //
.forAnnotation(aEndpoint) //
.placeholder() //
.withLayer(aTypeAdapter.getLayer()) //
.withRange(new VRange(aEndpoint.getBegin() - aWindowBegin,
aEndpoint.getEnd() - aWindowBegin)) //
.withRange(new VRange(aEndpoint.getBegin() - windowBegin,
aEndpoint.getEnd() - windowBegin)) //
.build();
aVDocument.add(placeholder);
return placeholder.getVid();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ private <T extends SpanAnnotationRequest_ImplBase<T>> T onRequest(TypeAdapter aA

@Override
public void onRender(TypeAdapter aAdapter, VDocument aResponse,
Map<AnnotationFS, VSpan> annoToSpanIdx, int aPageBegin, int aPageEnd)
Map<AnnotationFS, VSpan> annoToSpanIdx)
{
if (aAdapter.getLayer().isCrossSentence() || annoToSpanIdx.isEmpty()) {
return;
Expand All @@ -114,8 +114,8 @@ public void onRender(TypeAdapter aAdapter, VDocument aResponse,
// particular offset, even if it is not the start/end offset of a sentence.
NavigableMap<Integer, AnnotationFS> sentBeginIdx = new TreeMap<>();
NavigableMap<Integer, AnnotationFS> sentEndIdx = new TreeMap<>();
for (AnnotationFS sent : selectOverlapping(cas, getType(cas, Sentence.class), aPageBegin,
aPageEnd)) {
for (AnnotationFS sent : selectOverlapping(cas, getType(cas, Sentence.class),
aResponse.getWindowBegin(), aResponse.getWindowEnd())) {
sentBeginIdx.put(sent.getBegin(), sent);
sentEndIdx.put(sent.getEnd(), sent);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public abstract MoveSpanAnnotationRequest onMove(TypeAdapter aAdapter,
throws AnnotationException;

public void onRender(TypeAdapter aAdapter, VDocument aResponse,
Map<AnnotationFS, VSpan> annoToSpanIdx, int aPageBegin, int aPageEnd)
Map<AnnotationFS, VSpan> annoToSpanIdx)
{
// Nothing to do by default
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ private <T extends SpanAnnotationRequest_ImplBase<T>> T onRequest(TypeAdapter aA

@Override
public void onRender(TypeAdapter aAdapter, VDocument aResponse,
Map<AnnotationFS, VSpan> aAnnoToSpanIdx, int aPageBegin, int aPageEnd)
Map<AnnotationFS, VSpan> aAnnoToSpanIdx)
{
if (aAnnoToSpanIdx.isEmpty()) {
return;
Expand Down
Loading

0 comments on commit 73a1f2a

Please sign in to comment.