Search in sources :

Example 1 with IEquivalentConceptMerger

use of com.b2international.snowowl.snomed.reasoner.equivalence.IEquivalentConceptMerger in project snow-owl by b2ihealthcare.

the class SaveJobRequest method mergeEquivalentConcepts.

private Set<String> mergeEquivalentConcepts(final BranchContext context, final BulkRequestBuilder<TransactionContext> bulkRequestBuilder, final SnomedNamespaceAndModuleAssigner assigner) {
    if (!fixEquivalences) {
        return Collections.emptySet();
    }
    // XXX: Restrict merging to active components only
    final String expand = "equivalentConcepts(expand(" + "descriptions(active:true)," + "relationships(active:true)," + "inboundRelationships(active:true)," + "members(active:true)))";
    final Multimap<SnomedConcept, SnomedConcept> equivalentConcepts = HashMultimap.create();
    ClassificationRequests.prepareSearchEquivalentConceptSet().setLimit(SCROLL_LIMIT).setExpand(expand).filterByClassificationId(classificationId).stream(context).flatMap(EquivalentConceptSets::stream).filter(equivalentSet -> !equivalentSet.isUnsatisfiable()).forEach(equivalentSet -> {
        final List<SnomedConcept> conceptsToRemove = newArrayList(equivalentSet.getEquivalentConcepts());
        final SnomedConcept conceptToKeep = conceptsToRemove.remove(0);
        equivalentConcepts.putAll(conceptToKeep, conceptsToRemove);
    });
    // Are there any equivalent concepts present? or Were all equivalent concepts unsatisfiable?
    if (equivalentConcepts.isEmpty()) {
        return Collections.emptySet();
    }
    IEquivalentConceptMerger merger = Extensions.getFirstPriorityExtension(IEquivalentConceptMerger.EXTENSION_POINT, IEquivalentConceptMerger.class);
    if (merger == null) {
        merger = new IEquivalentConceptMerger.Default();
    }
    final String mergerName = merger.getClass().getSimpleName();
    LOG.info("Reasoner service will use {} for equivalent concept merging.", mergerName);
    final Set<String> conceptIdsToSkip = merger.merge(equivalentConcepts);
    final Set<String> conceptIdsToKeep = equivalentConcepts.keySet().stream().map(SnomedConcept::getId).collect(Collectors.toSet());
    // Prepare to provide namespace-module for inbound relationship source concepts as well
    final Set<String> relationshipChangeConceptIds = newHashSet(conceptIdsToKeep);
    // Add source concepts on new/about to be inactivated inbound relationships, pointing to "kept" concepts
    for (final SnomedConcept conceptToKeep : equivalentConcepts.keySet()) {
        for (final SnomedRelationship relationship : conceptToKeep.getInboundRelationships()) {
            if (relationship.getId().startsWith(IEquivalentConceptMerger.PREFIX_NEW)) {
                relationshipChangeConceptIds.add(relationship.getSourceId());
            } else if (!relationship.isActive()) {
                relationshipChangeConceptIds.add(relationship.getSourceId());
            }
        }
    }
    assigner.collectRelationshipNamespacesAndModules(relationshipChangeConceptIds, context);
    for (final SnomedConcept conceptToKeep : equivalentConcepts.keySet()) {
        for (final SnomedRelationship relationship : conceptToKeep.getInboundRelationships()) {
            // Already handled as another concept's outbound relationship
            if (relationship.getId() == null) {
                continue;
            }
            if (relationship.getId().startsWith(IEquivalentConceptMerger.PREFIX_NEW)) {
                relationship.setId(null);
                addComponent(bulkRequestBuilder, assigner, relationship);
            } else if (!relationship.isActive()) {
                removeOrDeactivate(bulkRequestBuilder, assigner, relationship);
            }
        }
        for (final SnomedRelationship relationship : conceptToKeep.getRelationships()) {
            // Already handled as another concept's inbound relationship
            if (relationship.getId() == null) {
                continue;
            }
            if (relationship.getId().startsWith(IEquivalentConceptMerger.PREFIX_NEW)) {
                relationship.setId(null);
                addComponent(bulkRequestBuilder, assigner, relationship);
            } else if (!relationship.isActive()) {
                removeOrDeactivate(bulkRequestBuilder, assigner, relationship);
            }
        }
    }
    // CD members are always "outbound", however, so the concept SCTID set can be reduced
    assigner.clear();
    assigner.collectConcreteDomainModules(conceptIdsToKeep, context);
    for (final SnomedConcept conceptToKeep : equivalentConcepts.keySet()) {
        for (final SnomedReferenceSetMember member : conceptToKeep.getMembers()) {
            if (member.getId().startsWith(IEquivalentConceptMerger.PREFIX_NEW)) {
                member.setId(null);
                addComponent(bulkRequestBuilder, assigner, member);
            } else if (member.getId().startsWith(IEquivalentConceptMerger.PREFIX_UPDATED)) {
                // Trim the prefix from the ID to restore its original form
                member.setId(member.getId().substring(IEquivalentConceptMerger.PREFIX_UPDATED.length()));
                bulkRequestBuilder.add(member.toUpdateRequest());
            } else if (!member.isActive()) {
                removeOrDeactivate(bulkRequestBuilder, assigner, member);
            }
        }
    }
    // Descriptions are also "outbound"
    assigner.clear();
    assigner.collectRelationshipNamespacesAndModules(conceptIdsToKeep, context);
    for (final SnomedConcept conceptToKeep : equivalentConcepts.keySet()) {
        for (final SnomedDescription description : conceptToKeep.getDescriptions()) {
            if (description.getId().startsWith(IEquivalentConceptMerger.PREFIX_NEW)) {
                description.setId(null);
                addComponent(bulkRequestBuilder, assigner, description);
            } else if (description.getId().startsWith(IEquivalentConceptMerger.PREFIX_UPDATED)) {
                // Trim the prefix from the ID to restore its original form
                description.setId(description.getId().substring(IEquivalentConceptMerger.PREFIX_UPDATED.length()));
                bulkRequestBuilder.add(description.toUpdateRequest());
            } else if (!description.isActive()) {
                removeOrDeactivate(bulkRequestBuilder, assigner, description);
            }
        }
    }
    // Inactivation of "removed" concepts also requires modules to be collected according to the assigner rules
    assigner.clear();
    assigner.collectRelationshipNamespacesAndModules(conceptIdsToSkip, context);
    for (final SnomedConcept conceptToRemove : equivalentConcepts.values()) {
        // Check if the concept needs to be removed or deactivated
        if (!conceptToRemove.isActive()) {
            removeOrDeactivate(bulkRequestBuilder, assigner, conceptToRemove);
        }
    }
    assigner.clear();
    return conceptIdsToSkip;
}
Also used : SnomedRelationshipIndexEntry(com.b2international.snowowl.snomed.datastore.index.entry.SnomedRelationshipIndexEntry) LoggerFactory(org.slf4j.LoggerFactory) RepositoryRequests(com.b2international.snowowl.core.repository.RepositoryRequests) HashMultimap(com.google.common.collect.HashMultimap) AccessControl(com.b2international.snowowl.core.authorization.AccessControl) Map(java.util.Map) IEquivalentConceptMerger(com.b2international.snowowl.snomed.reasoner.equivalence.IEquivalentConceptMerger) Sets.newHashSet(com.google.common.collect.Sets.newHashSet) Permission(com.b2international.snowowl.core.identity.Permission) ClassificationTracker(com.b2international.snowowl.snomed.reasoner.classification.ClassificationTracker) BulkRequestBuilder(com.b2international.snowowl.core.events.bulk.BulkRequestBuilder) SnomedNamespaceAndModuleAssigner(com.b2international.snowowl.snomed.datastore.id.assigner.SnomedNamespaceAndModuleAssigner) ImmutableMap(com.google.common.collect.ImmutableMap) Request(com.b2international.snowowl.core.events.Request) Set(java.util.Set) Commit(com.b2international.index.revision.Commit) NotNull(javax.validation.constraints.NotNull) Collectors(java.util.stream.Collectors) IProgressMonitor(org.eclipse.core.runtime.IProgressMonitor) List(java.util.List) DatastoreLockContextDescriptions(com.b2international.snowowl.core.internal.locks.DatastoreLockContextDescriptions) Lists.newArrayList(com.google.common.collect.Lists.newArrayList) BranchContext(com.b2international.snowowl.core.domain.BranchContext) SnomedCoreConfiguration(com.b2international.snowowl.snomed.datastore.config.SnomedCoreConfiguration) TerminologyResource(com.b2international.snowowl.core.TerminologyResource) Iterables(com.google.common.collect.Iterables) Locks(com.b2international.snowowl.core.locks.Locks) SubMonitor(org.eclipse.core.runtime.SubMonitor) com.b2international.snowowl.snomed.reasoner.domain(com.b2international.snowowl.snomed.reasoner.domain) Extensions(com.b2international.snowowl.core.plugin.Extensions) com.b2international.snowowl.snomed.core.domain(com.b2international.snowowl.snomed.core.domain) Multimap(com.google.common.collect.Multimap) Branch(com.b2international.snowowl.core.branch.Branch) Strings(com.google.common.base.Strings) BulkRequest(com.b2international.snowowl.core.events.bulk.BulkRequest) DEFAULT_NAMESPACE_AND_MODULE_ASSIGNER(com.b2international.snowowl.snomed.common.SnomedTerminologyComponentConstants.DEFAULT_NAMESPACE_AND_MODULE_ASSIGNER) RepositoryConfiguration(com.b2international.snowowl.core.config.RepositoryConfiguration) SnowOwlConfiguration(com.b2international.snowowl.core.config.SnowOwlConfiguration) BadRequestException(com.b2international.commons.exceptions.BadRequestException) Logger(org.slf4j.Logger) CommitResult(com.b2international.snowowl.core.request.CommitResult) com.b2international.snowowl.snomed.datastore.request(com.b2international.snowowl.snomed.datastore.request) NAMESPACE_AND_MODULE_ASSIGNER(com.b2international.snowowl.snomed.common.SnomedTerminologyComponentConstants.NAMESPACE_AND_MODULE_ASSIGNER) TransactionContext(com.b2international.snowowl.core.domain.TransactionContext) SnomedReferenceSetMember(com.b2international.snowowl.snomed.core.domain.refset.SnomedReferenceSetMember) NotEmpty(org.hibernate.validator.constraints.NotEmpty) LockedException(com.b2international.commons.exceptions.LockedException) User(com.b2international.snowowl.core.identity.User) SnomedRf2Headers(com.b2international.snowowl.snomed.common.SnomedRf2Headers) Collections(java.util.Collections) ReasonerApiException(com.b2international.snowowl.snomed.reasoner.exceptions.ReasonerApiException) SnomedReferenceSetMember(com.b2international.snowowl.snomed.core.domain.refset.SnomedReferenceSetMember) IEquivalentConceptMerger(com.b2international.snowowl.snomed.reasoner.equivalence.IEquivalentConceptMerger)

Aggregations

BadRequestException (com.b2international.commons.exceptions.BadRequestException)1 LockedException (com.b2international.commons.exceptions.LockedException)1 Commit (com.b2international.index.revision.Commit)1 TerminologyResource (com.b2international.snowowl.core.TerminologyResource)1 AccessControl (com.b2international.snowowl.core.authorization.AccessControl)1 Branch (com.b2international.snowowl.core.branch.Branch)1 RepositoryConfiguration (com.b2international.snowowl.core.config.RepositoryConfiguration)1 SnowOwlConfiguration (com.b2international.snowowl.core.config.SnowOwlConfiguration)1 BranchContext (com.b2international.snowowl.core.domain.BranchContext)1 TransactionContext (com.b2international.snowowl.core.domain.TransactionContext)1 Request (com.b2international.snowowl.core.events.Request)1 BulkRequest (com.b2international.snowowl.core.events.bulk.BulkRequest)1 BulkRequestBuilder (com.b2international.snowowl.core.events.bulk.BulkRequestBuilder)1 Permission (com.b2international.snowowl.core.identity.Permission)1 User (com.b2international.snowowl.core.identity.User)1 DatastoreLockContextDescriptions (com.b2international.snowowl.core.internal.locks.DatastoreLockContextDescriptions)1 Locks (com.b2international.snowowl.core.locks.Locks)1 Extensions (com.b2international.snowowl.core.plugin.Extensions)1 RepositoryRequests (com.b2international.snowowl.core.repository.RepositoryRequests)1 CommitResult (com.b2international.snowowl.core.request.CommitResult)1