Skip to content

Commit

Permalink
Terminology: Reimplementing 'subsumes()' and 'subsumedBy()' with colu…
Browse files Browse the repository at this point in the history
…mnar approach.
  • Loading branch information
piotrszul committed Oct 24, 2023
1 parent 04eda1f commit 2610247
Show file tree
Hide file tree
Showing 7 changed files with 209 additions and 212 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,28 @@ void testCount() {
.hasRows(expectedCountResult.changeValue(PATIENT_ID_bbd33563, 0L));
}



@Test
void testSimpleSubsumesAndSubsumedBy() {

setupSubsumes(terminologyService);
// Viral sinusitis (disorder) = http://snomed.info/sct|444814009 not in (PATIENT_ID_2b36c1e2,
// PATIENT_ID_bbd33563, PATIENT_ID_7001ad9c)
// Chronic sinusitis (disorder) = http://snomed.info/sct|40055000 in (PATIENT_ID_7001ad9c)

assertThatResultOf(ResourceType.CONDITION,
"code.subsumedBy(http://snomed.info/sct|40055000)")
.isElementPath(BooleanCollection.class)
.selectOrderedResult()
.hasRows(spark, "responses/ParserTest/testSimpleSubsumes-one.tsv");

assertThatResultOf(ResourceType.CONDITION,
"code.subsumedBy($this)")
.isElementPath(BooleanCollection.class)
.selectOrderedResult()
.hasRows(spark, "responses/ParserTest/testSimpleSubsumes-self.tsv");
}
@Test
void testSubsumesAndSubsumedBy() {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
01fac610-c309-46f8-9a0f-6b0f55c9915a false
031f1c86-16ec-42e1-a155-81456e778fed false
0447de38-1f2a-411c-9fd2-a9c62ab1f221 false
061521f0-7f7e-41a5-ad35-b30fe958dea7 false
06e446da-6d66-4d97-a457-4abf2a0d2e24 false
08b4f1b6-f99b-400d-90f1-ec5cc6ed1556 false
1146cf52-573f-4667-97c3-abf235f9a83b false
1452c50c-b0b9-472c-afb7-2f9e5a3c4717 false
171ad058-c082-46ab-b9cc-d7bba6e4e3cd true
1cea8432-f8a0-4746-ab5c-8f195fc07c55 false
1dcedab1-cf3c-46dc-859b-cc3fb63e8375 false
21372b39-2be0-4d0d-85c4-5d7e250d8f78 false
248e951c-e0ce-4e4b-afae-6273fd109c9d false
251ddff9-1588-4790-8f40-cd6ab1d9b7fc false
258191b8-2b42-4473-9ba2-be0ba3561767 false
29386b12-9af9-4c21-9f82-858998b388bb false
31393667-dd7f-4c94-90c3-6cde75c67d3e false
31925a68-7a48-412c-b4f8-aef92498dda1 false
38171e22-b35d-4161-be15-80243be37b99 false
39170d67-8205-4636-84d7-d8575115d14c false
4025ceb3-04a6-41fb-8569-16a8dcce7ccc false
46d69851-eca3-42e2-b142-88c5578f6cff false
475461a2-3bd2-43fd-a5aa-7ce424203ae8 false
4dd7824b-4b41-4402-bc42-de016e1bfcd9 false
5300158c-92cb-40fe-bc14-a449d7b3c1c5 false
5378726d-7f2b-4c83-9762-eaf385915fa7 false
549d3ef5-a05e-4b8e-acba-3d70f26a82f6 false
55cde383-2eb1-42d9-b5c6-698d6eade389 false
5a406b78-ae23-4b4f-a3c8-9d9ed2f9d325 false
5ef84858-0480-4a34-8f43-fc962fe627b2 false
6464e20b-55ec-4685-be3e-55bc3b9602d4 false
66b38727-96ea-43ad-bff7-5f4df5d779a9 false
6794fbaf-e715-4e22-bafa-b7e594550ff7 false
77fc5f45-e51d-41e2-8356-daa27ebd8268 false
7d18555a-54c9-4c0a-bf3b-6305d0392a2a false
7ed34fb1-0bbf-4c41-a101-1316ec483aa7 false
80787532-559e-4999-ac25-75c462ce4ef1 false
8922ff1b-4bc5-41b4-8512-5aad1517e2eb false
8ddb74fc-46d5-4e94-a0ee-6761b292ae95 false
8dfd419b-0b83-4ba7-8fe6-324e2f382bd6 false
8f3ad6ad-a457-484e-a455-f0711e77b2ba false
9e598086-27bb-4e50-8988-9a40eb3c178f false
9ed0f743-5a93-46ba-bf3f-e00c6f8c5bbc false
a16f311d-d6dc-486e-8eb0-7cd53a5333ee false
aa5a32b3-3993-4eb5-afce-489d0e7413cf false
abecd476-3911-4a6b-a1c6-b8ecea2fe63e false
ad679e19-3e17-4c67-8b0d-dd4f7d862207 false
b77b04ef-5eda-418c-a6fb-528a2d0a171a false
b8eccdce-7261-4402-9aa0-7360ae6bf53b false
b972a4a8-4f7e-4e9b-8e2c-71140bf0c6cc false
badbd940-9839-4472-aa66-3382d8823c80 false
bb9c4fc1-795a-4492-b065-1f497fe18bb2 false
be4b757d-70f1-464c-bb29-6f9a0f6cb05e false
c39927f7-d23a-475c-b325-c1de4b51e280 false
c879c300-7fdf-4b53-aa6a-a2b4a266b30c false
c892bf2f-a7bc-407e-9508-c778a9b8761c false
d12274a5-9e03-4c78-ae3e-6cc27e91d737 false
d554ba19-e081-4979-9c0c-a72cd6e5e8ea false
da8db730-f051-42d0-a2db-a3577d96e9bd false
db8c0b3e-48f0-43ac-aa03-9ae9a251cb82 false
df98a2ea-8129-4d1a-9a9f-13a0292f6d1d false
e2f8e85b-ed68-42a1-bae2-b5d7c2a69a76 false
e35f5823-4533-49e5-9652-79d733be6bef false
e620d7ee-6cfe-4f04-ba06-1d0b39f7624d false
e87fbe4b-74ef-44e4-8e36-70b2abb48895 false
eaee8845-e4ed-42e1-9098-99b3f7e14dc3 false
eaf99c09-419d-4162-8417-5a9d7e042cd4 false
eb373264-da60-4e98-af7c-e3021fdd8d4b false
f1dd0d5f-c410-484b-984c-2ba38cee79ba false
f1fd855c-802c-417a-ab7c-14a3c9daafc6 false
f41b6458-2358-43e7-ae34-d2a0fbe083d8 false
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
01fac610-c309-46f8-9a0f-6b0f55c9915a true
031f1c86-16ec-42e1-a155-81456e778fed true
0447de38-1f2a-411c-9fd2-a9c62ab1f221 true
061521f0-7f7e-41a5-ad35-b30fe958dea7 true
06e446da-6d66-4d97-a457-4abf2a0d2e24 true
08b4f1b6-f99b-400d-90f1-ec5cc6ed1556 true
1146cf52-573f-4667-97c3-abf235f9a83b true
1452c50c-b0b9-472c-afb7-2f9e5a3c4717 true
171ad058-c082-46ab-b9cc-d7bba6e4e3cd true
1cea8432-f8a0-4746-ab5c-8f195fc07c55 true
1dcedab1-cf3c-46dc-859b-cc3fb63e8375 true
21372b39-2be0-4d0d-85c4-5d7e250d8f78 true
248e951c-e0ce-4e4b-afae-6273fd109c9d true
251ddff9-1588-4790-8f40-cd6ab1d9b7fc true
258191b8-2b42-4473-9ba2-be0ba3561767 true
29386b12-9af9-4c21-9f82-858998b388bb true
31393667-dd7f-4c94-90c3-6cde75c67d3e true
31925a68-7a48-412c-b4f8-aef92498dda1 true
38171e22-b35d-4161-be15-80243be37b99 true
39170d67-8205-4636-84d7-d8575115d14c true
4025ceb3-04a6-41fb-8569-16a8dcce7ccc true
46d69851-eca3-42e2-b142-88c5578f6cff true
475461a2-3bd2-43fd-a5aa-7ce424203ae8 true
4dd7824b-4b41-4402-bc42-de016e1bfcd9 true
5300158c-92cb-40fe-bc14-a449d7b3c1c5 true
5378726d-7f2b-4c83-9762-eaf385915fa7 true
549d3ef5-a05e-4b8e-acba-3d70f26a82f6 true
55cde383-2eb1-42d9-b5c6-698d6eade389 true
5a406b78-ae23-4b4f-a3c8-9d9ed2f9d325 true
5ef84858-0480-4a34-8f43-fc962fe627b2 true
6464e20b-55ec-4685-be3e-55bc3b9602d4 true
66b38727-96ea-43ad-bff7-5f4df5d779a9 true
6794fbaf-e715-4e22-bafa-b7e594550ff7 true
77fc5f45-e51d-41e2-8356-daa27ebd8268 true
7d18555a-54c9-4c0a-bf3b-6305d0392a2a true
7ed34fb1-0bbf-4c41-a101-1316ec483aa7 true
80787532-559e-4999-ac25-75c462ce4ef1 true
8922ff1b-4bc5-41b4-8512-5aad1517e2eb true
8ddb74fc-46d5-4e94-a0ee-6761b292ae95 true
8dfd419b-0b83-4ba7-8fe6-324e2f382bd6 true
8f3ad6ad-a457-484e-a455-f0711e77b2ba true
9e598086-27bb-4e50-8988-9a40eb3c178f true
9ed0f743-5a93-46ba-bf3f-e00c6f8c5bbc true
a16f311d-d6dc-486e-8eb0-7cd53a5333ee true
aa5a32b3-3993-4eb5-afce-489d0e7413cf true
abecd476-3911-4a6b-a1c6-b8ecea2fe63e true
ad679e19-3e17-4c67-8b0d-dd4f7d862207 true
b77b04ef-5eda-418c-a6fb-528a2d0a171a true
b8eccdce-7261-4402-9aa0-7360ae6bf53b true
b972a4a8-4f7e-4e9b-8e2c-71140bf0c6cc true
badbd940-9839-4472-aa66-3382d8823c80 true
bb9c4fc1-795a-4492-b065-1f497fe18bb2 true
be4b757d-70f1-464c-bb29-6f9a0f6cb05e true
c39927f7-d23a-475c-b325-c1de4b51e280 true
c879c300-7fdf-4b53-aa6a-a2b4a266b30c true
c892bf2f-a7bc-407e-9508-c778a9b8761c true
d12274a5-9e03-4c78-ae3e-6cc27e91d737 true
d554ba19-e081-4979-9c0c-a72cd6e5e8ea true
da8db730-f051-42d0-a2db-a3577d96e9bd true
db8c0b3e-48f0-43ac-aa03-9ae9a251cb82 true
df98a2ea-8129-4d1a-9a9f-13a0292f6d1d true
e2f8e85b-ed68-42a1-bae2-b5d7c2a69a76 true
e35f5823-4533-49e5-9652-79d733be6bef true
e620d7ee-6cfe-4f04-ba06-1d0b39f7624d true
e87fbe4b-74ef-44e4-8e36-70b2abb48895 true
eaee8845-e4ed-42e1-9098-99b3f7e14dc3 true
eaf99c09-419d-4162-8417-5a9d7e042cd4 true
eb373264-da60-4e98-af7c-e3021fdd8d4b true
f1dd0d5f-c410-484b-984c-2ba38cee79ba true
f1fd855c-802c-417a-ab7c-14a3c9daafc6 true
f41b6458-2358-43e7-ae34-d2a0fbe083d8 true
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import au.csiro.pathling.fhirpath.collection.StringCollection;
import au.csiro.pathling.fhirpath.column.ColumnCtx;
import au.csiro.pathling.fhirpath.validation.FhirpathFunction;
import au.csiro.pathling.sql.Terminology;
import java.util.Optional;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
Expand Down Expand Up @@ -93,9 +94,9 @@ public static StringCollection designation(@Nonnull final CodingCollection input
}

/**
* A function that takes a set of Codings or CodeableConcepts as inputs and returns a set of boolean
* values, based upon whether each item is present within the ValueSet identified by the supplied
* URL.
* A function that takes a set of Codings or CodeableConcepts as inputs and returns a set of
* boolean values, based upon whether each item is present within the ValueSet identified by the
* supplied URL.
*
* @author John Grimes
* @see <a href="https://pathling.csiro.au/docs/fhirpath/functions.html#memberof">memberOf</a>
Expand All @@ -107,4 +108,35 @@ public static BooleanCollection memberOf(@Nonnull final CodingCollection input,
input.getCtx().callUDF("member_of", valueSetURL.getCtx().singular())
);
}


/**
* A function that takes a set of Codings or CodeableConcepts as inputs and returns a set of
* boolean values whether based upon whether each item subsumes one or more Codings or
* CodeableConcepts in the argument set.
*
* @author John Grimes
* @author Piotr Szul
* @see <a href="https://hl7.org/fhir/R4/fhirpath.html#functions">Additional functions</a>
*/
@FhirpathFunction
public static BooleanCollection subsumes(@Nonnull final CodingCollection input,
@Nonnull final CodingCollection codes) {
return BooleanCollection.build(Terminology.subsumes(input.getColumn(), codes.getColumn()));
}

/**
* A function that takes a set of Codings or CodeableConcepts as inputs and returns a set of
* boolean values whether based upon whether each item is subsumedBy one or more Codings or
* CodeableConcepts in the argument set.
*
* @author John Grimes
* @author Piotr Szul
* @see <a href="https://hl7.org/fhir/R4/fhirpath.html#functions">Additional functions</a>
*/
@FhirpathFunction
public static BooleanCollection subsumedBy(@Nonnull final CodingCollection input,
@Nonnull final CodingCollection codes) {
return BooleanCollection.build(Terminology.subsumed_by(input.getColumn(), codes.getColumn()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public Object resolveArgument(@Nonnull final Parameter parameter,
// "Parameter " + parameter + " is not nullable and no argument was provided"));
} else if (Collection.class.isAssignableFrom(parameter.getType())) {
// evaluate collection types
return argument.eval(input, evaluationContext).getPureValue();
return resolveCollection(argument.eval(input, evaluationContext).getPureValue(), parameter);
} else if (CollectionExpression.class.isAssignableFrom(parameter.getType())) {
// bind with context
return (CollectionExpression) (c -> argument.eval(c, evaluationContext).getPureValue());
Expand All @@ -97,19 +97,19 @@ public Object resolveArgument(@Nonnull final Parameter parameter,
}
}

public static Object resolveInput(@Nonnull final Collection input,
@Nonnull final Parameter inputParameter) {
if (CodingCollection.class.isAssignableFrom(inputParameter.getType())) {
public static Object resolveCollection(@Nonnull final Collection collection,
@Nonnull final Parameter parameter) {
if (CodingCollection.class.isAssignableFrom(parameter.getType())) {
// evaluate collection types
return input.asCoding().orElseThrow();
} else if (Collection.class.isAssignableFrom(inputParameter.getType())) {
return collection.asCoding().orElseThrow();
} else if (Collection.class.isAssignableFrom(parameter.getType())) {
// evaluate collection types
return input;
return collection;
} else {
throw new RuntimeException("Cannot resolve input:" + inputParameter);
throw new RuntimeException("Cannot resolve input:" + parameter);
}
}

@Override
@Nonnull
public One<Collection> eval(@Nonnull final FunctionInput functionInput) {
Expand All @@ -130,7 +130,7 @@ public One<Collection> eval(@Nonnull final FunctionInput functionInput) {

// we also may need to map the input here ....

final Object input = resolveInput(functionInput.getInput(), method.getParameters()[0]);
final Object input = resolveCollection(functionInput.getInput(), method.getParameters()[0]);

final Object[] invocationArgs = Stream.concat(Stream.of(input),
resolvedArguments).toArray(Object[]::new);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import au.csiro.pathling.fhirpath.function.TerminologyFunctions;
import au.csiro.pathling.fhirpath.function.UntilFunction;
import au.csiro.pathling.fhirpath.function.WrappedFunction;
import au.csiro.pathling.fhirpath.function.terminology.SubsumesFunction;
import au.csiro.pathling.fhirpath.function.terminology.TranslateFunction;
import com.google.common.collect.ImmutableMap.Builder;

Expand All @@ -26,8 +25,6 @@ public class StaticFunctionRegistry extends InMemoryFunctionRegistry<NamedFuncti
public StaticFunctionRegistry() {
super(new Builder<String, NamedFunction>()
.put("resolve", new ResolveFunction())
.put("subsumes", new SubsumesFunction())
.put("subsumedBy", new SubsumesFunction(true))
.put("iif", new IifFunction())
.put("translate", new TranslateFunction())
.put("until", new UntilFunction())
Expand Down
Loading

0 comments on commit 2610247

Please sign in to comment.