From abe46f2364260ef62f128bfdc164e7837c3ddffe Mon Sep 17 00:00:00 2001 From: Richard Eckart de Castilho Date: Tue, 26 Dec 2023 12:15:52 +0100 Subject: [PATCH] #2696 - Document-level recommendations - Fix suggestion registry class name - Wrote a very few words of documentation - Bit of cleaning --- .../MetadataSuggestionSupport.java | 14 +++-- .../recommendation/api/SuggestionSupport.java | 63 +++++++++++++++---- .../RecommenderServiceAutoConfiguration.java | 4 +- .../relation/RelationSuggestionSupport.java | 2 +- .../service/RecommendationServiceImpl.java | 8 ++- ...ava => SuggestionSupportRegistryImpl.java} | 4 +- .../span/SpanSuggestionSupport.java | 4 +- .../developer-guide/recommendation.adoc | 25 +++++++- ...ommendationServiceImplIntegrationTest.java | 4 +- 9 files changed, 98 insertions(+), 30 deletions(-) rename inception/inception-recommendation/src/main/java/de/tudarmstadt/ukp/inception/recommendation/service/{LayerRecommendtionSupportRegistryImpl.java => SuggestionSupportRegistryImpl.java} (94%) diff --git a/inception/inception-layer-docmetadata/src/main/java/de/tudarmstadt/ukp/inception/ui/core/docanno/recommendation/MetadataSuggestionSupport.java b/inception/inception-layer-docmetadata/src/main/java/de/tudarmstadt/ukp/inception/ui/core/docanno/recommendation/MetadataSuggestionSupport.java index 84a418097f2..76274a57a35 100644 --- a/inception/inception-layer-docmetadata/src/main/java/de/tudarmstadt/ukp/inception/ui/core/docanno/recommendation/MetadataSuggestionSupport.java +++ b/inception/inception-layer-docmetadata/src/main/java/de/tudarmstadt/ukp/inception/ui/core/docanno/recommendation/MetadataSuggestionSupport.java @@ -172,15 +172,15 @@ public void calculateSuggestionVisibility(Strin { LOG.trace("calculateSuggestionVisibility() for layer {} on document {}", aLayer, aDocument); - var type = aCas.getTypeSystem().getType(aLayer.getName()); - if (type == null) { + var predictedType = aCas.getTypeSystem().getType(aLayer.getName()); + if (predictedType == null) { // The type does not exist in the type system of the CAS. Probably it has not // been upgraded to the latest version of the type system yet. If this is the case, // we'll just skip. return; } - var annotations = aCas. select(type).asList(); + var annotations = aCas. select(predictedType).asList(); var suggestionsForLayer = aRecommendations.stream() // Only suggestions for the given layer @@ -194,7 +194,7 @@ public void calculateSuggestionVisibility(Strin var adapter = schemaService.getAdapter(aLayer); var traits = adapter.getTraits(DocumentMetadataLayerTraits.class).get(); for (var feature : schemaService.listSupportedFeatures(aLayer)) { - var feat = type.getFeatureByBaseName(feature.getName()); + var feat = predictedType.getFeatureByBaseName(feature.getName()); if (feat == null) { // The feature does not exist in the type system of the CAS. Probably it has not @@ -267,14 +267,16 @@ static void hideSuggestionsRejectedOrSkipped(MetadataSuggestion aSuggestion, } @Override - public LearningRecord toLearningRecord(SourceDocument aDocument, String aUsername, + public LearningRecord toLearningRecord(SourceDocument aDocument, String aDataOwner, AnnotationSuggestion aSuggestion, AnnotationFeature aFeature, LearningRecordUserAction aUserAction, LearningRecordChangeLocation aLocation) { var record = new LearningRecord(); - record.setUser(aUsername); + record.setUser(aDataOwner); record.setSourceDocument(aDocument); record.setUserAction(aUserAction); + record.setOffsetBegin(-1); + record.setOffsetEnd(-1); record.setOffsetBegin2(-1); record.setOffsetEnd2(-1); record.setAnnotation(aSuggestion.getLabel()); diff --git a/inception/inception-recommendation-api/src/main/java/de/tudarmstadt/ukp/inception/recommendation/api/SuggestionSupport.java b/inception/inception-recommendation-api/src/main/java/de/tudarmstadt/ukp/inception/recommendation/api/SuggestionSupport.java index 3d83e2ada1a..26aa7ed1e34 100644 --- a/inception/inception-recommendation-api/src/main/java/de/tudarmstadt/ukp/inception/recommendation/api/SuggestionSupport.java +++ b/inception/inception-recommendation-api/src/main/java/de/tudarmstadt/ukp/inception/recommendation/api/SuggestionSupport.java @@ -41,29 +41,70 @@ public interface SuggestionSupport extends Extension { + /** + * @param aCtx + * the extraction context containing all important information. + * @return the suggestions extracted from the prediction CAS provided in the context. + */ + List extractSuggestions(ExtractionContext aCtx); + + /** + * @return the renderer used to render suggestions provided by this suggestion support. + */ + Optional getRenderer(); + + /** + * Calculate the visibility for the given suggestions. The suggestions must have been produced + * by this suggestion support. Also, they must all be from the same layer - be sure to process + * one layer at a time. The suggestions may come from different recommenders though. + */ + void calculateSuggestionVisibility(String aSessionOwner, + SourceDocument aDocument, CAS aCas, String aDataOwner, AnnotationLayer aLayer, + Collection> aRecommendations, int aWindowBegin, int aWindowEnd); + + /** + * Accept the given suggestion. + * + * @param aSuggestion + * the suggestion to accept. + * @return the annotation created from the suggestion. + * @throws AnnotationException + * if there was a problem creating the annotation. + */ AnnotationBaseFS acceptSuggestion(String aSessionOwner, SourceDocument aDocument, String aDataOwner, CAS aCas, TypeAdapter aAdapter, AnnotationFeature aFeature, AnnotationSuggestion aSuggestion, LearningRecordChangeLocation aLocation, LearningRecordUserAction aAction) throws AnnotationException; + /** + * Reject the given suggestion. + * + * @param aSuggestion + * the suggestion to reject. + * @throws AnnotationException + * if there was a problem rejecting the annotation. + */ void rejectSuggestion(String aSessionOwner, SourceDocument aDocument, String aDataOwner, - AnnotationSuggestion suggestion, LearningRecordChangeLocation aAction) + AnnotationSuggestion aSuggestion, LearningRecordChangeLocation aAction) throws AnnotationException; + /** + * Skip the given suggestion. + * + * @param aSuggestion + * the suggestion to skip. + * @throws AnnotationException + * if there was a problem skipping the annotation. + */ void skipSuggestion(String aSessionOwner, SourceDocument aDocument, String aDataOwner, - AnnotationSuggestion suggestion, LearningRecordChangeLocation aAction) + AnnotationSuggestion aSuggestion, LearningRecordChangeLocation aAction) throws AnnotationException; - void calculateSuggestionVisibility(String aSessionOwner, - SourceDocument aDocument, CAS aCas, String aDataOwner, AnnotationLayer aLayer, - Collection> aRecommendations, int aWindowBegin, int aWindowEnd); - - LearningRecord toLearningRecord(SourceDocument aDocument, String aUsername, + /** + * Create a learning record from the given suggestion. + */ + LearningRecord toLearningRecord(SourceDocument aDocument, String aDataOwner, AnnotationSuggestion aSuggestion, AnnotationFeature aFeature, LearningRecordUserAction aUserAction, LearningRecordChangeLocation aLocation); - - Optional getRenderer(); - - List extractSuggestions(ExtractionContext aCtx); } diff --git a/inception/inception-recommendation/src/main/java/de/tudarmstadt/ukp/inception/recommendation/config/RecommenderServiceAutoConfiguration.java b/inception/inception-recommendation/src/main/java/de/tudarmstadt/ukp/inception/recommendation/config/RecommenderServiceAutoConfiguration.java index 983f3a8b2b7..74054b5325d 100644 --- a/inception/inception-recommendation/src/main/java/de/tudarmstadt/ukp/inception/recommendation/config/RecommenderServiceAutoConfiguration.java +++ b/inception/inception-recommendation/src/main/java/de/tudarmstadt/ukp/inception/recommendation/config/RecommenderServiceAutoConfiguration.java @@ -56,7 +56,7 @@ import de.tudarmstadt.ukp.inception.recommendation.project.RecommenderProjectSettingsPanelFactory; import de.tudarmstadt.ukp.inception.recommendation.relation.RelationSuggestionSupport; import de.tudarmstadt.ukp.inception.recommendation.render.RecommendationRenderer; -import de.tudarmstadt.ukp.inception.recommendation.service.LayerRecommendtionSupportRegistryImpl; +import de.tudarmstadt.ukp.inception.recommendation.service.SuggestionSupportRegistryImpl; import de.tudarmstadt.ukp.inception.recommendation.service.RecommendationServiceImpl; import de.tudarmstadt.ukp.inception.recommendation.service.RecommenderFactoryRegistryImpl; import de.tudarmstadt.ukp.inception.recommendation.sidebar.RecommendationSidebarFactory; @@ -232,6 +232,6 @@ public RelationSuggestionSupport relationRecommendationSupport( public SuggestionSupportRegistry layerRecommendtionSupportRegistry( @Lazy @Autowired(required = false) List aExtensions) { - return new LayerRecommendtionSupportRegistryImpl(aExtensions); + return new SuggestionSupportRegistryImpl(aExtensions); } } diff --git a/inception/inception-recommendation/src/main/java/de/tudarmstadt/ukp/inception/recommendation/relation/RelationSuggestionSupport.java b/inception/inception-recommendation/src/main/java/de/tudarmstadt/ukp/inception/recommendation/relation/RelationSuggestionSupport.java index dde66836c6a..23abea7b499 100644 --- a/inception/inception-recommendation/src/main/java/de/tudarmstadt/ukp/inception/recommendation/relation/RelationSuggestionSupport.java +++ b/inception/inception-recommendation/src/main/java/de/tudarmstadt/ukp/inception/recommendation/relation/RelationSuggestionSupport.java @@ -422,7 +422,7 @@ public List extractSuggestions(ExtractionContext ctx) .withId(RelationSuggestion.NEW_ID) // .withGeneration(ctx.getGeneration()) // .withRecommender(ctx.getRecommender()) // - .withDocumentName(ctx.getDocument().getName()) // + .withDocument(ctx.getDocument()) // .withPosition(position) // .withLabel(label) // .withUiLabel(label) // diff --git a/inception/inception-recommendation/src/main/java/de/tudarmstadt/ukp/inception/recommendation/service/RecommendationServiceImpl.java b/inception/inception-recommendation/src/main/java/de/tudarmstadt/ukp/inception/recommendation/service/RecommendationServiceImpl.java index 77899ba1534..3c74088be1a 100644 --- a/inception/inception-recommendation/src/main/java/de/tudarmstadt/ukp/inception/recommendation/service/RecommendationServiceImpl.java +++ b/inception/inception-recommendation/src/main/java/de/tudarmstadt/ukp/inception/recommendation/service/RecommendationServiceImpl.java @@ -1831,7 +1831,7 @@ static ReconciliationResult reconcile(Predictions aActivePredictions, SourceDocu s.getScore() == newSuggestion.getScore() && // Objects.equals(s.getScoreExplanation(), newSuggestion.getScoreExplanation())) - .collect(toList()); + .toList(); if (existingSuggestions.isEmpty()) { addedSuggestions.add(newSuggestion); @@ -1864,8 +1864,10 @@ public void calculateSuggestionVisibility(Strin SourceDocument aDocument, CAS aCas, String aDataOwner, AnnotationLayer aLayer, Collection> aRecommendations, int aWindowBegin, int aWindowEnd) { - var maybeSuggestion = aRecommendations.stream().filter(group -> !group.isEmpty()) - .flatMap(group -> group.stream()).findAny(); + var maybeSuggestion = aRecommendations.stream() // + .filter(group -> !group.isEmpty()) // + .flatMap(group -> group.stream()) // + .findAny(); if (maybeSuggestion.isEmpty()) { return; diff --git a/inception/inception-recommendation/src/main/java/de/tudarmstadt/ukp/inception/recommendation/service/LayerRecommendtionSupportRegistryImpl.java b/inception/inception-recommendation/src/main/java/de/tudarmstadt/ukp/inception/recommendation/service/SuggestionSupportRegistryImpl.java similarity index 94% rename from inception/inception-recommendation/src/main/java/de/tudarmstadt/ukp/inception/recommendation/service/LayerRecommendtionSupportRegistryImpl.java rename to inception/inception-recommendation/src/main/java/de/tudarmstadt/ukp/inception/recommendation/service/SuggestionSupportRegistryImpl.java index 57742ff5de1..8e82dbffcfc 100644 --- a/inception/inception-recommendation/src/main/java/de/tudarmstadt/ukp/inception/recommendation/service/LayerRecommendtionSupportRegistryImpl.java +++ b/inception/inception-recommendation/src/main/java/de/tudarmstadt/ukp/inception/recommendation/service/SuggestionSupportRegistryImpl.java @@ -28,12 +28,12 @@ import de.tudarmstadt.ukp.inception.recommendation.api.model.Recommender; import de.tudarmstadt.ukp.inception.support.extensionpoint.ExtensionPoint_ImplBase; -public class LayerRecommendtionSupportRegistryImpl +public class SuggestionSupportRegistryImpl extends ExtensionPoint_ImplBase implements SuggestionSupportRegistry { @Autowired - public LayerRecommendtionSupportRegistryImpl( + public SuggestionSupportRegistryImpl( @Lazy @Autowired(required = false) List aExtensions) { super(aExtensions); diff --git a/inception/inception-recommendation/src/main/java/de/tudarmstadt/ukp/inception/recommendation/span/SpanSuggestionSupport.java b/inception/inception-recommendation/src/main/java/de/tudarmstadt/ukp/inception/recommendation/span/SpanSuggestionSupport.java index b97b01aac50..33e91c97c6c 100644 --- a/inception/inception-recommendation/src/main/java/de/tudarmstadt/ukp/inception/recommendation/span/SpanSuggestionSupport.java +++ b/inception/inception-recommendation/src/main/java/de/tudarmstadt/ukp/inception/recommendation/span/SpanSuggestionSupport.java @@ -441,13 +441,13 @@ static void hideSuggestionsRejectedOrSkipped(SpanSuggestion aSuggestion, } @Override - public LearningRecord toLearningRecord(SourceDocument aDocument, String aUsername, + public LearningRecord toLearningRecord(SourceDocument aDocument, String aDataOwner, AnnotationSuggestion aSuggestion, AnnotationFeature aFeature, LearningRecordUserAction aUserAction, LearningRecordChangeLocation aLocation) { var pos = ((SpanSuggestion) aSuggestion).getPosition(); var record = new LearningRecord(); - record.setUser(aUsername); + record.setUser(aDataOwner); record.setSourceDocument(aDocument); record.setUserAction(aUserAction); record.setOffsetBegin(pos.getBegin()); diff --git a/inception/inception-recommendation/src/main/resources/META-INF/asciidoc/developer-guide/recommendation.adoc b/inception/inception-recommendation/src/main/resources/META-INF/asciidoc/developer-guide/recommendation.adoc index adf95053ad6..28137482fb7 100644 --- a/inception/inception-recommendation/src/main/resources/META-INF/asciidoc/developer-guide/recommendation.adoc +++ b/inception/inception-recommendation/src/main/resources/META-INF/asciidoc/developer-guide/recommendation.adoc @@ -15,7 +15,7 @@ // limitations under the License. [[sect_recommendation]] -= Recommendation += Recommenders system For information on the different recommenders, please refer to <>. @@ -31,3 +31,26 @@ For information on the different recommenders, please refer to <