Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for additional data during CQL evaluation #2420

Merged
merged 20 commits into from
Mar 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@
"doseNumberPositiveInt": 2,
"seriesDosesPositiveInt": 2
}
]
],
"location": {
"reference": "Location/nairobi-047"
}
}
}
]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022-2023 Google LLC
* Copyright 2022-2024 Google LLC
*
* 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 @@ -71,7 +71,7 @@ class D_FhirJsonParserBenchmark {
val fhirHelpersLibrary = jsonParser.parseResource(fhirHelpersJson) as Library

assertThat(immunityCheckLibrary.id).isEqualTo("Library/ImmunityCheck-1.0.0")
assertThat(immunityCheckLibrary.content[0].data.size).isEqualTo(575)
assertThat(immunityCheckLibrary.content[0].data.size).isEqualTo(810)
assertThat(fhirHelpersLibrary.id).isEqualTo("Library/FHIRHelpers-4.0.1")
assertThat(fhirHelpersLibrary.content[0].data.size).isEqualTo(17845)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022-2023 Google LLC
* Copyright 2022-2024 Google LLC
*
* 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 @@ -84,9 +84,9 @@ class F_CqlEvaluatorBenchmark {

val results =
fhirOperator.evaluateLibrary(
"http://localhost/Library/ImmunityCheck|1.0.0",
"d4d35004-24f8-40e4-8084-1ad75924514f",
setOf("CompletedImmunization"),
libraryUrl = "http://localhost/Library/ImmunityCheck|1.0.0",
patientId = "d4d35004-24f8-40e4-8084-1ad75924514f",
expressions = setOf("CompletedImmunization"),
) as Parameters

assertThat(results.getParameterBool("CompletedImmunization")).isTrue()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import kotlinx.coroutines.runBlocking
import org.hl7.fhir.instance.model.api.IBaseResource
import org.hl7.fhir.r4.model.Bundle
import org.hl7.fhir.r4.model.Library
import org.hl7.fhir.r4.model.Location
import org.hl7.fhir.r4.model.Parameters
import org.junit.Before
import org.junit.Rule
Expand Down Expand Up @@ -122,15 +123,58 @@ class FhirOperatorLibraryEvaluateTest {
// Load Library that checks if Patient has taken a vaccine
knowledgeManager.install(copy("/immunity-check/ImmunityCheck.json"))

// Evaluates a specific Patient
val results =
fhirOperator.evaluateLibrary(
libraryUrl = "http://localhost/Library/ImmunityCheck|1.0.0",
patientId = "d4d35004-24f8-40e4-8084-1ad75924514f",
expressions = setOf("CompletedImmunization"),
) as Parameters

assertThat(results.getParameterBool("CompletedImmunization")).isTrue()
}

@Test
fun evaluateImmunityCheckWithAdditionalData() = runBlocking {
val patientImmunizationHistory = load("/immunity-check/ImmunizationHistory.json") as Bundle
for (entry in patientImmunizationHistory.entry) {
fhirEngine.create(entry.resource)
}

// Load Library that checks if Patient has taken a vaccine
knowledgeManager.install(copy("/immunity-check/ImmunityCheck.json"))
knowledgeManager.install(copy("/immunity-check/FhirHelpers.json"))

val location =
"""
{
"resourceType": "Location",
"id": "nairobi-047",
"name": "Nairobi mobile clinic"
}
"""
.trimIndent()

val additionalDataBundle =
Bundle().apply {
addEntry(
Bundle.BundleEntryComponent().apply {
resource = jsonParser.parseResource(location) as Location
},
)
}

// Evaluates a specific Patient
val results =
fhirOperator.evaluateLibrary(
"http://localhost/Library/ImmunityCheck|1.0.0",
"d4d35004-24f8-40e4-8084-1ad75924514f",
setOf("CompletedImmunization"),
null,
additionalDataBundle,
null,
) as Parameters

assertThat(results.getParameterBool("CompletedImmunization")).isTrue()
assertThat(results.hasParameter("GetFinalDoseWithLocationData")).isTrue()
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,70 +71,6 @@ internal constructor(
private val measureProcessor = R4MeasureProcessor(repository, measureEvaluationOptions)
private val planDefinitionProcessor = PlanDefinitionProcessor(repository, evaluationSettings)

/**
* The function evaluates a FHIR library against the database.
*
* NOTE: The API may internally result in a blocking IO operation. The user should call the API
* from a worker thread or it may throw [BlockingMainThreadException] exception.
*
* @param libraryUrl the url of the Library to evaluate
* @param expressions names of expressions in the Library to evaluate. If null the result contains
* all evaluations or variables in library.
* @return a Parameters resource that contains an evaluation result for each expression requested.
* Or if expressions param is null then result contains all evaluations or variables in given
* library.
*/
@WorkerThread
fun evaluateLibrary(libraryUrl: String, expressions: Set<String>?): IBaseParameters {
return evaluateLibrary(libraryUrl, null, null, expressions)
}

/**
* The function evaluates a FHIR library against a patient's records.
*
* NOTE: The API may internally result in a blocking IO operation. The user should call the API
* from a worker thread or it may throw [BlockingMainThreadException] exception.
*
* @param libraryUrl the url of the Library to evaluate
* @param patientId the Id of the patient to be evaluated
* @param expressions names of expressions in the Library to evaluate. If null the result contains
* all evaluations or variables in library.
* @return a Parameters resource that contains an evaluation result for each expression requested.
* Or if expressions param is null then result contains all evaluations or variables in given
* library.
*/
@WorkerThread
fun evaluateLibrary(
libraryUrl: String,
patientId: String,
expressions: Set<String>?,
): IBaseParameters {
return evaluateLibrary(libraryUrl, patientId, null, expressions)
}

/**
* The function evaluates a FHIR library against the database.
*
* NOTE: The API may internally result in a blocking IO operation. The user should call the API
* from a worker thread or it may throw [BlockingMainThreadException] exception.
*
* @param libraryUrl the url of the Library to evaluate
* @param parameters list of parameters to be passed to the CQL library
* @param expressions names of expressions in the Library to evaluate. If null the result contains
* all evaluations or variables in library.
* @return a Parameters resource that contains an evaluation result for each expression requested.
* Or if expressions param is null then result contains all evaluations or variables in given
* library.
*/
@WorkerThread
fun evaluateLibrary(
libraryUrl: String,
parameters: Parameters,
expressions: Set<String>?,
): IBaseParameters {
return evaluateLibrary(libraryUrl, null, parameters, expressions)
}

/**
* The function evaluates a FHIR library against the database.
*
Expand All @@ -144,6 +80,8 @@ internal constructor(
* @param libraryUrl the url of the Library to evaluate
* @param patientId the Id of the patient to be evaluated, if applicable
* @param parameters list of parameters to be passed to the CQL library, if applicable
* @param additionalData Bundle of additional resources to be passed to the CQL library, if
* applicable
* @param expressions names of expressions in the Library to evaluate. If null the result contains
* all evaluations or variables in library.
* @return a Parameters resource that contains an evaluation result for each expression requested.
Expand All @@ -153,15 +91,16 @@ internal constructor(
@WorkerThread
fun evaluateLibrary(
jingtang10 marked this conversation as resolved.
Show resolved Hide resolved
libraryUrl: String,
patientId: String?,
parameters: Parameters?,
expressions: Set<String>?,
patientId: String? = null,
parameters: Parameters? = null,
additionalData: IBaseBundle? = null,
expressions: Set<String>? = null,
): IBaseParameters {
return libraryProcessor.evaluate(
/* url = */ libraryUrl,
/* patientId = */ patientId,
/* parameters = */ parameters,
/* additionalData = */ null,
/* additionalData = */ additionalData,
/* expressions = */ expressions,
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022-2023 Google LLC
* Copyright 2022-2024 Google LLC
*
* 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 @@ -116,9 +116,9 @@ class FhirOperatorLibraryEvaluateJavaTest {
// Evaluates a specific Patient
val results =
fhirOperator.evaluateLibrary(
"http://localhost/Library/ImmunityCheck|1.0.0",
"d4d35004-24f8-40e4-8084-1ad75924514f",
setOf("CompletedImmunization"),
libraryUrl = "http://localhost/Library/ImmunityCheck|1.0.0",
patientId = "d4d35004-24f8-40e4-8084-1ad75924514f",
expressions = setOf("CompletedImmunization"),
) as Parameters

assertThat(results.getParameterBool("CompletedImmunization")).isTrue()
Expand All @@ -140,7 +140,9 @@ class FhirOperatorLibraryEvaluateJavaTest {
knowledgeManager.install(writeToFile(library))

// Evaluates expression without any extra data
val results = fhirOperator.evaluateLibrary(library.url, setOf("GetName")) as Parameters
val results =
fhirOperator.evaluateLibrary(libraryUrl = library.url, expressions = setOf("GetName"))
as Parameters

assertThat((results.parameterFirstRep.value as StringType).value).isEqualTo("MyName")
}
Expand Down Expand Up @@ -171,7 +173,12 @@ class FhirOperatorLibraryEvaluateJavaTest {
}

// Evaluates the library with a parameter
val results = fhirOperator.evaluateLibrary(library.url, params, setOf("SumOne")) as Parameters
val results =
fhirOperator.evaluateLibrary(
libraryUrl = library.url,
parameters = params,
expressions = setOf("SumOne"),
) as Parameters

assertThat((results.parameterFirstRep.value as DecimalType).value).isEqualTo(BigDecimal(2))
}
Expand Down
Loading