Skip to content

Commit

Permalink
Merge pull request #1290 from b2ihealthcare/feature/SO-6106-subproper…
Browse files Browse the repository at this point in the history
…ty-of-support-9x

 SO-6106: "Sub...PropertyOf" support for axiom-relationship conversions (9.x)
  • Loading branch information
cmark authored May 8, 2024
2 parents 41846b3 + baa7e74 commit 3d89dac
Show file tree
Hide file tree
Showing 6 changed files with 197 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2011-2023 B2i Healthcare, https://b2ihealthcare.com
* Copyright 2011-2024 B2i Healthcare, https://b2ihealthcare.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -277,6 +277,9 @@ private Concepts() { }

//Unapproved attribute hierarchy root
public static final String UNAPPROVED_ATTRIBUTE = "408739003";

// Concept model attribute hierarchy roots, starting with INT 20240301
public static final String ANNOTATION_ATTRIBUTE = "1295447006";

// Concepts that require special care when classifying
public static final String ROLE_GROUP = "609096000";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
import com.b2international.snowowl.snomed.datastore.internal.id.SnomedIdentifierTest;
import com.b2international.snowowl.snomed.datastore.internal.id.reservations.ReservationImplTest;
import com.b2international.snowowl.snomed.datastore.internal.id.reservations.SnomedIdentifierReservationServiceImplTest;
import com.b2international.snowowl.snomed.datastore.request.SnomedOWLExpressionConverterTest;
import com.b2international.snowowl.snomed.datastore.request.SnomedOWLRelationshipConverterTest;
import com.b2international.snowowl.snomed.validation.SnomedQueryValidationRuleEvaluatorTest;

/**
Expand Down Expand Up @@ -67,6 +69,9 @@
SnomedQueryValidationRuleEvaluatorTest.class,
// Query optimization
SnomedQueryOptimizerTest.class,
// OWL expression conversion tests
SnomedOWLExpressionConverterTest.class,
SnomedOWLRelationshipConverterTest.class,
})
public class AllSnomedDatastoreTests {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Copyright 2024 B2i Healthcare Ltd, http://b2ihealthcare.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.b2international.snowowl.snomed.datastore.request;

import static org.junit.Assert.*;

import java.util.List;

import org.elasticsearch.core.Set;
import org.junit.Test;

import com.b2international.snowowl.snomed.common.SnomedConstants.Concepts;
import com.b2international.snowowl.snomed.datastore.index.entry.SnomedOWLRelationshipDocument;
import com.google.common.collect.Iterables;

/**
* @since 7.24.3
*/
public class SnomedOWLExpressionConverterTest {

@Test
public void testSubObjectPropertyOf() {
testSubPropertyOf("SubObjectPropertyOf");
}

@Test
public void testSubDataPropertyOf() {
testSubPropertyOf("SubDataPropertyOf");
}

@Test
public void testSubAnnotationPropertyOf() {
testSubPropertyOf("SubAnnotationPropertyOf");
}

private void testSubPropertyOf(String subPropertyOfAxiom) {
SnomedOWLExpressionConverter converter = new SnomedOWLExpressionConverter(() -> Set.of());

// XXX: Using nonsensical but valid SCTIDs
SnomedOWLExpressionConverterResult converterResult = converter.toSnomedOWLRelationships(
Concepts.FINDING_SITE,
String.format("%s(:%s :%s)", subPropertyOfAxiom, Concepts.FINDING_SITE, Concepts.AMBIGUOUS));

assertNull(converterResult.getGciAxiomRelationships());

final List<SnomedOWLRelationshipDocument> relationships = converterResult.getClassAxiomRelationships();
assertEquals(1, relationships.size());

final SnomedOWLRelationshipDocument relationship = Iterables.getOnlyElement(relationships);
assertEquals(Concepts.IS_A, relationship.getTypeId());
assertEquals(Concepts.AMBIGUOUS, relationship.getDestinationId());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* Copyright 2024 B2i Healthcare Ltd, http://b2ihealthcare.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.b2international.snowowl.snomed.datastore.request;

import static org.junit.Assert.assertEquals;

import java.util.Collection;
import java.util.List;

import org.elasticsearch.core.Set;
import org.junit.Test;

import com.b2international.snowowl.snomed.common.SnomedConstants.Concepts;
import com.b2international.snowowl.snomed.datastore.index.entry.SnomedOWLRelationshipDocument;

/**
* @since 7.24.3
*/
public class SnomedOWLRelationshipConverterTest {

@Test
public void testSubClassOf() {
testSubPropertyOf(
"SubClassOf",
Set.of(),
Set.of(),
Set.of(),
Concepts.DEVICE
);
}

@Test
public void testSubObjectPropertyOf() {
testSubPropertyOf(
"SubObjectPropertyOf",
Set.of(Long.parseLong(Concepts.CONCEPT_MODEL_OBJECT_ATTRIBUTE)),
Set.of(),
Set.of(),
Concepts.CONCEPT_MODEL_OBJECT_ATTRIBUTE
);
}

@Test
public void testSubDataPropertyOf() {
testSubPropertyOf(
"SubDataPropertyOf",
Set.of(),
Set.of(Long.parseLong(Concepts.CONCEPT_MODEL_DATA_ATTRIBUTE)),
Set.of(),
Concepts.CONCEPT_MODEL_DATA_ATTRIBUTE
);
}

@Test
public void testSubAnnotationPropertyOf() {
testSubPropertyOf(
"SubAnnotationPropertyOf",
Set.of(),
Set.of(),
Set.of(Long.parseLong(Concepts.ANNOTATION_ATTRIBUTE)),
Concepts.ANNOTATION_ATTRIBUTE
);
}

private void testSubPropertyOf(
String subPropertyOfAxiom,
Collection<Long> objectAttributes,
Collection<Long> dataAttributes,
Collection<Long> annotationAttributes,
String destinationId
) {
SnomedOWLRelationshipConverter converter = new SnomedOWLRelationshipConverter(
Set.of(),
objectAttributes,
dataAttributes,
annotationAttributes);

// XXX: Using nonsensical but valid SCTIDs
final List<SnomedOWLRelationshipDocument> owlRelationships = List.of(
SnomedOWLRelationshipDocument.create(Concepts.IS_A, destinationId, 0)
);

final String expectedExpression = String.format("%s(:%s :%s)", subPropertyOfAxiom, Concepts.FINDING_SITE, destinationId);
final String actualExpression = converter.fromSnomedOwlRelationships(
false,
true,
Concepts.FINDING_SITE,
owlRelationships
);

assertEquals(expectedExpression, actualExpression);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@ public final class SnomedOWLExpressionConverter {
"SubClassOf",
"EquivalentClasses",
"SubObjectPropertyOf",
"SubDataPropertyOf");
"SubDataPropertyOf",
"SubAnnotationPropertyOf"
);

private final Supplier<AxiomRelationshipConversionService> conversionService;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,21 @@ public final class SnomedOWLRelationshipConverter {

private final Supplier<AxiomRelationshipConversionService> conversionService;

public SnomedOWLRelationshipConverter(final Set<Long> ungroupedAttributes, final Collection<Long> objectAttributes, final Collection<Long> dataAttributes) {
public SnomedOWLRelationshipConverter(
final Set<Long> ungroupedAttributes,
final Collection<Long> objectAttributes,
final Collection<Long> dataAttributes,
final Collection<Long> annotationAttributes
) {
this.conversionService = Suppliers.memoize(() -> {
final Stopwatch stopwatch = Stopwatch.createStarted();
final AxiomRelationshipConversionService service = withTccl(() -> new AxiomRelationshipConversionService(ungroupedAttributes, objectAttributes, dataAttributes));
final AxiomRelationshipConversionService service = withTccl(() -> new AxiomRelationshipConversionService(
ungroupedAttributes,
objectAttributes,
dataAttributes,
annotationAttributes)
);

LOG.debug("SNOMED OWL Toolkit conversion service initialization took {}", TimeUtil.toString(stopwatch));
return service;
});
Expand Down

0 comments on commit 3d89dac

Please sign in to comment.