use of com.b2international.snowowl.snomed.core.domain.refset.SnomedReferenceSetMember in project snow-owl by b2ihealthcare.
the class SnomedReferenceSetMemberConverter method expandTargetComponent.
private void expandTargetComponent(List<SnomedReferenceSetMember> results) {
if (expand().containsKey(SnomedReferenceSetMember.Expand.TARGET_COMPONENT)) {
final Options expandOptions = expand().get(SnomedReferenceSetMember.Expand.TARGET_COMPONENT, Options.class);
final Multimap<String, SnomedReferenceSetMember> membersByTargetComponent = HashMultimap.create();
for (SnomedReferenceSetMember member : results) {
final Map<String, Object> props = member.getProperties();
if (props.containsKey(SnomedRf2Headers.FIELD_TARGET_COMPONENT_ID)) {
membersByTargetComponent.put(((String) props.get(SnomedRf2Headers.FIELD_TARGET_COMPONENT_ID)), member);
}
}
final Multimap<ComponentCategory, String> targetComponentIdsByCategory = Multimaps.index(membersByTargetComponent.keySet(), new Function<String, ComponentCategory>() {
@Override
public ComponentCategory apply(String id) {
return SnomedIdentifiers.getComponentCategory(id);
}
});
for (ComponentCategory category : targetComponentIdsByCategory.keySet()) {
final Collection<String> targetComponentIds = targetComponentIdsByCategory.get(category);
final Map<String, ? extends SnomedCoreComponent> componentsById = Maps.uniqueIndex(getComponents(category, targetComponentIds, expandOptions.get("expand", Options.class)), IComponent::getId);
for (String targetComponentId : targetComponentIds) {
final SnomedCoreComponent targetComponent = componentsById.get(targetComponentId);
if (targetComponent != null) {
for (SnomedReferenceSetMember member : membersByTargetComponent.get(targetComponentId)) {
final Map<String, Object> newProps = newHashMap(member.getProperties());
newProps.put(SnomedReferenceSetMember.Expand.TARGET_COMPONENT, targetComponent);
((SnomedReferenceSetMember) member).setProperties(newProps);
}
}
}
}
}
}
use of com.b2international.snowowl.snomed.core.domain.refset.SnomedReferenceSetMember in project snow-owl by b2ihealthcare.
the class SnomedReferenceSetMemberConverter method expandReferencedComponent.
private void expandReferencedComponent(List<SnomedReferenceSetMember> results) {
if (expand().containsKey(SnomedReferenceSetMember.Expand.REFERENCED_COMPONENT)) {
Options expandOptions = expand().get(SnomedReferenceSetMember.Expand.REFERENCED_COMPONENT, Options.class);
final Multimap<String, SnomedReferenceSetMember> referencedComponentIdToMemberMap = collectReferencedComponentIds(results);
final Multimap<ComponentCategory, String> componentCategoryToIdMap = collectReferencedComponentCategories(referencedComponentIdToMemberMap);
for (ComponentCategory category : componentCategoryToIdMap.keySet()) {
expandComponentCategory(expandOptions, referencedComponentIdToMemberMap, componentCategoryToIdMap, category);
}
}
}
use of com.b2international.snowowl.snomed.core.domain.refset.SnomedReferenceSetMember in project snow-owl by b2ihealthcare.
the class ReasonerTaxonomyBuilder method addActiveConcreteDomainMembers.
/*
* XXX: sortedMembers should be sorted by referenced component ID; we can not verify this in advance
*/
public ReasonerTaxonomyBuilder addActiveConcreteDomainMembers(final Stream<SnomedReferenceSetMember> sortedMembers) {
entering("Registering active concrete domain members using stream");
final List<ConcreteDomainFragment> statedFragments = new ArrayList<>(SCROLL_LIMIT);
final List<ConcreteDomainFragment> inferredFragments = new ArrayList<>(SCROLL_LIMIT);
final List<ConcreteDomainFragment> additionalGroupedFragments = new ArrayList<>(SCROLL_LIMIT);
String lastReferencedComponentId = "";
for (final List<SnomedReferenceSetMember> chunk : Iterables.partition(sortedMembers::iterator, SCROLL_LIMIT)) {
for (final SnomedReferenceSetMember member : chunk) {
final String characteristicTypeId = (String) member.getProperties().get(SnomedRf2Headers.FIELD_CHARACTERISTIC_TYPE_ID);
if (member.isActive() && SnomedRefSetUtil.getConcreteDomainRefSetMap().containsValue(member.getRefsetId()) && CD_CHARACTERISTIC_TYPE_IDS.contains(characteristicTypeId) && !excludedModuleIds.contains(member.getModuleId())) {
final String referencedComponentId = member.getReferencedComponent().getId();
if (lastReferencedComponentId.isEmpty()) {
lastReferencedComponentId = referencedComponentId;
} else if (!lastReferencedComponentId.equals(referencedComponentId)) {
if (conceptMap.containsKey(lastReferencedComponentId)) {
statedConcreteDomainMembers.putAll(lastReferencedComponentId, statedFragments);
inferredConcreteDomainMembers.putAll(lastReferencedComponentId, inferredFragments);
additionalGroupedConcreteDomainMembers.putAll(lastReferencedComponentId, additionalGroupedFragments);
} else {
LOGGER.debug("Not registering CD members for concept {} as it is inactive.", lastReferencedComponentId);
}
statedFragments.clear();
inferredFragments.clear();
additionalGroupedFragments.clear();
lastReferencedComponentId = referencedComponentId;
}
final String memberId = member.getId();
final long refsetId = Long.parseLong(member.getRefsetId());
final String serializedValue = (String) member.getProperties().get(SnomedRf2Headers.FIELD_VALUE);
final Integer group = (Integer) member.getProperties().get(SnomedRf2Headers.FIELD_RELATIONSHIP_GROUP);
final long typeId = Long.parseLong((String) member.getProperties().get(SnomedRf2Headers.FIELD_TYPE_ID));
final ConcreteDomainFragment fragment = new ConcreteDomainFragment(memberId, refsetId, group, serializedValue, typeId, // XXX: "injected" CD members will not set this flag correctly, but they should only be used in equivalence checks
false);
if (Concepts.STATED_RELATIONSHIP.equals(characteristicTypeId)) {
statedFragments.add(fragment);
} else if (Concepts.ADDITIONAL_RELATIONSHIP.equals(characteristicTypeId) && group > 0) {
additionalGroupedFragments.add(fragment);
} else if (Concepts.INFERRED_RELATIONSHIP.equals(characteristicTypeId)) {
inferredFragments.add(fragment);
}
}
}
}
if (!lastReferencedComponentId.isEmpty()) {
if (conceptMap.containsKey(lastReferencedComponentId)) {
statedConcreteDomainMembers.putAll(lastReferencedComponentId, statedFragments);
inferredConcreteDomainMembers.putAll(lastReferencedComponentId, inferredFragments);
additionalGroupedConcreteDomainMembers.putAll(lastReferencedComponentId, additionalGroupedFragments);
} else {
LOGGER.debug("Not registering CD members for concept {} as it is inactive.", lastReferencedComponentId);
}
statedFragments.clear();
inferredFragments.clear();
additionalGroupedFragments.clear();
}
leaving("Registering active concrete domain members using stream");
return this;
}
use of com.b2international.snowowl.snomed.core.domain.refset.SnomedReferenceSetMember in project snow-owl by b2ihealthcare.
the class SnomedDescriptionAcceptabilityUpdateRequest method doExecute.
@Override
protected void doExecute(TransactionContext context, SnomedComponentDocument componentToUpdate) {
final Iterable<SnomedReferenceSetMember> existingMembers = create ? Collections.emptySet() : SnomedRequests.prepareSearchMember().all().filterByReferencedComponent(componentToUpdate.getId()).filterByRefSetType(Collections.singleton(SnomedRefSetType.LANGUAGE)).build().execute(context);
final Map<String, Acceptability> newLanguageMembersToCreate = newHashMap(newAcceptabilityMap);
final ModuleIdProvider moduleIdSupplier = context.service(ModuleIdProvider.class);
// check if there are existing matches
for (SnomedReferenceSetMember existingMember : existingMembers) {
final String acceptabilityId = (String) existingMember.getProperties().get(SnomedRf2Headers.FIELD_ACCEPTABILITY_ID);
final Acceptability acceptability = Acceptability.getByConceptId(acceptabilityId);
final String languageReferenceSetId = existingMember.getRefsetId();
if (null == acceptability) {
continue;
}
final SnomedRefSetMemberIndexEntry.Builder updatedMember = SnomedRefSetMemberIndexEntry.builder(existingMember);
final SnomedRefSetMemberIndexEntry oldRevision = updatedMember.build();
if (acceptability.equals(newLanguageMembersToCreate.get(languageReferenceSetId))) {
// Exact match: make sure that the member is active
if (ensureMemberActive(context, existingMember, updatedMember)) {
context.update(oldRevision, updatedMember.build());
}
// Remove it from the working list, as we have found a match
newLanguageMembersToCreate.remove(languageReferenceSetId);
} else if (newLanguageMembersToCreate.containsKey(languageReferenceSetId)) {
// Change acceptability, set status to active if required, place it in the supplied module
final Acceptability newAcceptability = newLanguageMembersToCreate.get(languageReferenceSetId);
updatedMember.field(SnomedRf2Headers.FIELD_ACCEPTABILITY_ID, newAcceptability.getConceptId());
ensureMemberActive(context, existingMember, updatedMember);
updateModule(context, existingMember, updatedMember, moduleIdSupplier.apply(componentToUpdate));
unsetEffectiveTime(existingMember, updatedMember);
context.update(oldRevision, updatedMember.build());
newLanguageMembersToCreate.remove(languageReferenceSetId);
} else {
// Not acceptable in this language reference set, remove or inactivate if already released
if (removeOrDeactivate(context, existingMember, updatedMember)) {
context.update(oldRevision, updatedMember.build());
}
}
}
for (final Entry<String, Acceptability> languageMemberEntry : newLanguageMembersToCreate.entrySet()) {
SnomedComponents.newLanguageMember().withAcceptability(languageMemberEntry.getValue()).withRefSet(languageMemberEntry.getKey()).withModuleId(moduleIdSupplier.apply(componentToUpdate)).withReferencedComponent(componentToUpdate.getId()).addTo(context);
}
}
use of com.b2international.snowowl.snomed.core.domain.refset.SnomedReferenceSetMember 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;
}
Aggregations