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

Expose overloaded FHIR Operator API for evaluateMeasure #13

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.google.android.fhir.workflow;

import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.r4.model.Measure;
import org.hl7.fhir.r4.model.MeasureReport;
import org.hl7.fhir.r4.model.Parameters;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.opencds.cqf.fhir.api.Repository;
import org.opencds.cqf.fhir.cr.measure.MeasureEvaluationOptions;
import org.opencds.cqf.fhir.cr.measure.common.MeasureEvalType;
import org.opencds.cqf.fhir.cr.measure.common.SubjectProvider;
import org.opencds.cqf.fhir.cr.measure.r4.R4MeasureProcessor;

import java.util.List;

public class FhirEngineR4MeasureProcessor extends R4MeasureProcessor {
public FhirEngineR4MeasureProcessor(Repository repository, MeasureEvaluationOptions measureEvaluationOptions) {
super(repository, measureEvaluationOptions);
}

public FhirEngineR4MeasureProcessor(Repository repository, MeasureEvaluationOptions measureEvaluationOptions, SubjectProvider subjectProvider) {
super(repository, measureEvaluationOptions, subjectProvider);
}

public MeasureReport evaluateMeasure(Measure measure, String periodStart, String periodEnd, String reportType, List<String> subjectIds, IBaseBundle additionalData, Parameters parameters, MeasureEvalType evalType) {
return super.evaluateMeasure(measure, periodStart, periodEnd, reportType, subjectIds, additionalData, parameters, evalType);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023-2024 Google LLC
* Copyright 2023-2025 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 @@ -31,15 +31,16 @@ import org.hl7.fhir.instance.model.api.IBaseParameters
import org.hl7.fhir.instance.model.api.IBaseResource
import org.hl7.fhir.r4.model.CanonicalType
import org.hl7.fhir.r4.model.IdType
import org.hl7.fhir.r4.model.Measure
import org.hl7.fhir.r4.model.MeasureReport
import org.hl7.fhir.r4.model.Parameters
import org.hl7.fhir.r4.model.PlanDefinition
import org.hl7.fhir.r4.model.Reference
import org.opencds.cqf.fhir.cql.EvaluationSettings
import org.opencds.cqf.fhir.cql.LibraryEngine
import org.opencds.cqf.fhir.cr.measure.MeasureEvaluationOptions
import org.opencds.cqf.fhir.cr.measure.common.MeasureEvalType
import org.opencds.cqf.fhir.cr.measure.common.MeasureReportType
import org.opencds.cqf.fhir.cr.measure.r4.R4MeasureProcessor
import org.opencds.cqf.fhir.cr.plandefinition.PlanDefinitionProcessor
import org.opencds.cqf.fhir.utility.monad.Eithers
import org.opencds.cqf.fhir.utility.repository.ProxyRepository
Expand Down Expand Up @@ -72,8 +73,8 @@ internal constructor(
MeasureEvaluationOptions().apply { evaluationSettings = [email protected] }

private val libraryProcessor = LibraryEngine(repository, evaluationSettings)
private val measureProcessor = FhirEngineR4MeasureProcessor(repository, measureEvaluationOptions)
private val planDefinitionProcessor = PlanDefinitionProcessor(repository, evaluationSettings)
private val measureProcessor = R4MeasureProcessor(repository, measureEvaluationOptions)

/**
* The function evaluates a FHIR library against the database.
Expand Down Expand Up @@ -154,6 +155,58 @@ internal constructor(
return report
}

@WorkerThread
fun evaluateMeasure(
measure: Measure,
start: String,
end: String,
reportType: String,
subjectId: String? = null,
practitioner: String? = null,
additionalData: IBaseBundle? = null,
parameters: Parameters? = null,
): MeasureReport {
val subject =
if (!practitioner.isNullOrBlank()) {
checkAndAddType(practitioner, "Practitioner")
} else if (!subjectId.isNullOrBlank()) {
checkAndAddType(subjectId, "Patient")
} else {
// List of null is required to run population-level measures
null
}

val subjectIds = if (subject == null) listOf() else listOf(subject)

val evalType =
MeasureEvalType.fromCode(reportType)
.orElse(
if (subjectIds.isNotEmpty()) {
MeasureEvalType.SUBJECT
} else {
MeasureEvalType.POPULATION
},
) as MeasureEvalType

val report =
measureProcessor.evaluateMeasure(
/* measure = */ measure,
/* periodStart = */ start,
/* periodEnd = */ end,
/* reportType = */ reportType,
/* subjectIds = */ subjectIds,
/* additionalData = */ additionalData,
/* parameters = */ parameters,
/* evalType = */ evalType,
)

// add subject reference for non-individual reportTypes
if (report.type.name == MeasureReportType.SUMMARY.name && !subject.isNullOrBlank()) {
report.setSubject(Reference(subject))
}
return report
}

/**
* Generates a [CarePlan] based on the provided inputs.
*
Expand Down