use of com.b2international.snowowl.snomed.core.domain.SnomedDescriptions in project snow-owl by b2ihealthcare.
the class SnomedValidationIssueDetailExtension method getAffectedComponentLabels.
@SuppressWarnings("unchecked")
private Map<String, String> getAffectedComponentLabels(BranchContext context, Map<String, Object> ruleParameters, final Set<String> conceptIds) {
boolean useFsn = ruleParameters.containsKey(ValidationConfiguration.USE_FSN) ? (boolean) ruleParameters.get(ValidationConfiguration.USE_FSN) : false;
Set<String> types;
if (useFsn) {
types = Set.of(Concepts.FULLY_SPECIFIED_NAME);
} else {
types = SnomedRequests.prepareGetSynonyms().build().execute(context).stream().map(SnomedConcept::getId).collect(Collectors.toSet());
}
List<ExtendedLocale> locales;
if (ruleParameters.containsKey(ValidationConfiguration.LOCALES)) {
locales = (List<ExtendedLocale>) ruleParameters.get(ValidationConfiguration.LOCALES);
} else {
locales = List.of();
}
final Map<String, String> affectedComponentLabelsByConcept = new HashMap<>();
for (List<String> partition : Iterables.partition(conceptIds, SCROLL_SIZE)) {
SnomedDescriptions descriptions = SnomedRequests.prepareSearchDescription().all().filterByActive(true).filterByConcepts(partition).filterByType(types).build().execute(context);
Map<String, SnomedDescription> preferredDescriptions = SnomedDescriptionUtils.indexBestPreferredByConceptId(context, descriptions, locales);
preferredDescriptions.forEach((id, description) -> affectedComponentLabelsByConcept.put(id, description.getTerm()));
}
return affectedComponentLabelsByConcept;
}
use of com.b2international.snowowl.snomed.core.domain.SnomedDescriptions in project snow-owl by b2ihealthcare.
the class DescriptionChangeConverter method expand.
@Override
public void expand(final List<DescriptionChange> results) {
if (!expand().containsKey(DescriptionChange.Expand.DESCRIPTION)) {
return;
}
/*
* Depending on the CD member change search request, we might need to issue
* SNOMED CT searches against multiple branches; find out which ones we have.
*/
final Multimap<String, DescriptionChange> itemsByBranch = getItemsByBranch(results);
// Check if we only need to load inferred CD members in their entirety
final Options expandOptions = expand().getOptions(DescriptionChange.Expand.DESCRIPTION);
final boolean inferredOnly = expandOptions.getBoolean("inferredOnly");
final Options descriptionExpandOptions = expandOptions.getOptions("expand");
final Options conceptOptions = descriptionExpandOptions.getOptions("concept");
final boolean needsConcept = descriptionExpandOptions.keySet().contains("concept");
for (final String branch : itemsByBranch.keySet()) {
final Collection<DescriptionChange> itemsForCurrentBranch = itemsByBranch.get(branch);
/*
* Expand concept on "new" descriptions via a separate search request, they will
* be different from the concept on the "origin" description.
*/
if (needsConcept) {
final List<ReasonerDescription> blankDescriptions = itemsForCurrentBranch.stream().filter(c -> ChangeNature.NEW.equals(c.getChangeNature())).map(DescriptionChange::getDescription).collect(Collectors.toList());
final Multimap<String, ReasonerDescription> descriptionsByConceptId = FluentIterable.from(blankDescriptions).index(ReasonerDescription::getConceptId);
final Set<String> conceptIds = descriptionsByConceptId.keySet();
final Request<BranchContext, SnomedConcepts> conceptSearchRequest = SnomedRequests.prepareSearchConcept().filterByIds(conceptIds).setLimit(conceptIds.size()).setExpand(conceptOptions.get("expand", Options.class)).setLocales(locales()).build();
final SnomedConcepts concepts = new BranchRequest<>(branch, new RevisionIndexReadRequest<>(conceptSearchRequest)).execute(context());
for (final SnomedConcept concept : concepts) {
final String conceptId = concept.getId();
final Collection<ReasonerDescription> descriptionsForConcept = descriptionsByConceptId.get(conceptId);
for (final ReasonerDescription description : descriptionsForConcept) {
description.setConcept(concept);
}
}
}
/*
* Then fetch all the required descriptions. Note that the same "origin"
* description might be used for multiple eg. "new" counterparts.
*/
final Set<String> descriptionIds = itemsForCurrentBranch.stream().filter(c -> !inferredOnly || ChangeNature.NEW.equals(c.getChangeNature())).map(c -> c.getDescription().getOriginDescriptionId()).collect(Collectors.toSet());
final Request<BranchContext, SnomedDescriptions> descriptionSearchRequest = SnomedRequests.prepareSearchDescription().filterByIds(descriptionIds).setLimit(descriptionIds.size()).setExpand(descriptionExpandOptions).setLocales(locales()).build();
final SnomedDescriptions descriptions = new BranchRequest<>(branch, new RevisionIndexReadRequest<>(descriptionSearchRequest)).execute(context());
final Map<String, SnomedDescription> descriptionsById = Maps.uniqueIndex(descriptions, SnomedDescription::getId);
for (final DescriptionChange item : itemsForCurrentBranch) {
final ReasonerDescription reasonerDescription = item.getDescription();
final String descriptionId = reasonerDescription.getOriginDescriptionId();
switch(item.getChangeNature()) {
case NEW:
{
final SnomedDescription expandedDescription = descriptionsById.get(descriptionId);
reasonerDescription.setAcceptabilityMap(expandedDescription.getAcceptabilityMap());
reasonerDescription.setCaseSignificanceId(expandedDescription.getCaseSignificanceId());
// reasonerDescription.setConcept(...) is already set earlier (or expanded)
reasonerDescription.setLanguageCode(expandedDescription.getLanguageCode());
// reasonerMember.setReleased(...) is already set
reasonerDescription.setTerm(expandedDescription.getTerm());
reasonerDescription.setType(expandedDescription.getType());
}
break;
case REDUNDANT:
if (!inferredOnly) {
final SnomedDescription expandedDescription = descriptionsById.get(descriptionId);
reasonerDescription.setAcceptabilityMap(expandedDescription.getAcceptabilityMap());
reasonerDescription.setCaseSignificanceId(expandedDescription.getCaseSignificanceId());
reasonerDescription.setConcept(expandedDescription.getConcept());
reasonerDescription.setLanguageCode(expandedDescription.getLanguageCode());
// reasonerMember.setReleased(...) is already set
reasonerDescription.setTerm(expandedDescription.getTerm());
reasonerDescription.setType(expandedDescription.getType());
}
break;
default:
throw new IllegalStateException(String.format("Unexpected description change '%s' found with SCTID '%s'.", item.getChangeNature(), item.getDescription().getOriginDescriptionId()));
}
}
}
}
use of com.b2international.snowowl.snomed.core.domain.SnomedDescriptions in project snow-owl by b2ihealthcare.
the class NamespaceIdProvider method extractNamespaceIds.
default Map<String, String> extractNamespaceIds(BranchContext context, final Collection<String> namespaceConceptIds, boolean ignoreInvalidValues) {
final Set<String> mutableNamespaceConceptIds = Sets.newHashSet(namespaceConceptIds);
final Map<String, String> namespacesByNamespaceConceptId = new HashMap<>(mutableNamespaceConceptIds.size());
// Keep only valid SCTIDs passed in to the filter
if (ignoreInvalidValues) {
mutableNamespaceConceptIds.removeIf(id -> !SnomedIdentifiers.isValid(id));
} else {
final Set<String> invalidNamespaceConceptIds = mutableNamespaceConceptIds.stream().filter(id -> !SnomedIdentifiers.isValid(id)).collect(ImmutableSortedSet.toImmutableSortedSet(Comparator.naturalOrder()));
if (!invalidNamespaceConceptIds.isEmpty()) {
throw new BadRequestException("The following namespaceConceptId values are invalid SNOMED CT Concept identifiers, %s", invalidNamespaceConceptIds.toString());
}
}
/*
* The International core namespace concept will not have an FSN matching the pattern,
* so remove it from the set, and convert it to the empty namespace directly.
*/
if (mutableNamespaceConceptIds.remove(Concepts.CORE_NAMESPACE)) {
namespacesByNamespaceConceptId.put(Concepts.CORE_NAMESPACE, "");
}
// Find the FSN of namespace SCTIDs
SnomedRequests.prepareSearchDescription().filterByActive(true).filterByType(Concepts.FULLY_SPECIFIED_NAME).filterByConcepts(mutableNamespaceConceptIds).setFields(SnomedDescriptionIndexEntry.Fields.ID, SnomedDescriptionIndexEntry.Fields.CONCEPT_ID, SnomedDescriptionIndexEntry.Fields.TERM).setLimit(1000).stream(context).flatMap(SnomedDescriptions::stream).forEach(fsn -> {
// Extract namespace from description terms
final Matcher matcher = NAMESPACE_PATTERN.matcher(fsn.getTerm());
if (matcher.matches()) {
namespacesByNamespaceConceptId.put(fsn.getConceptId(), matcher.group(1));
}
});
return Map.copyOf(namespacesByNamespaceConceptId);
}
Aggregations