projecttacoma / fqm-execution

fqm-execution is a library that allows users to calculate FHIR-based electronic Clinical Quality Measures (eCQMs) and retrieve the results in a variety of formats
https://projecttacoma.github.io/fqm-execution/
Apache License 2.0
18 stars 6 forks source link

Calculation for Stratification does not consider associated population #306

Closed mcmcphillips closed 1 month ago

mcmcphillips commented 3 months ago

Summary

Calculations for stratifications do not take into account their associated populations. Given a measure with a stratification that evaluates to true, and an associated population that evaluates to false, the stratification result is still true.

External Tracking Ticket

Expected Behavior

Given a stratification that evaluates true, with it's associated population that does not evaluate true, the stratification result should return false.

Version or Commit

"fqm-execution": "^1.3.3"

Inputs (e.g. Measure Bundle, Patient Bundle, CQL Library)

options: { measureBundle.json patientBundle.json valuesets.txt

      includeClauseResults: false,
      trustMetaProfile: true,
      buildStatementLevelHTML: true,
      measurementPeriodStart: 2025-01-01T00:00:00.000+00:00
      measurementPeriodEnd: 2025-12-31T23:59:59.999+00:00,
    },

Relevant Calculation Options (e.g. Measurement Period, meta.profile Validation)

cql-to-elm Version Used for Measure Logic Translation (if known)

3.10.0

Any Additional Info

hossenlopp commented 3 months ago

Hi @mcmcphillips,

Thanks for submitting this issue with most of the data we need. Just have one question, are you using the "detailed" output of fqm-execution or the MeasureReport output?

In general in the detailed results the stratifications are treated as a "filter" to be applied to the population(s) they belong to. So they will be evaluated and be true or false regardless of results of the population(s) results. When creating a MeasureReport from the detailed results, the stratified results will have stratifier applied to the population(s) and if the patient isn't in a population, they will not count in that stratification. This may be what your implementation should look to doing if you are working from the detailed results.

The detailed results always evaluate the stratifications since in a measure testing environment it may be useful to see the results of the stratifications separately from the population(s).

In a future sprint we will prioritize looking deeper into this issue and how the usage of cqfm-appliesTo may affect fqm-execution.

-Chris

mcmcphillips commented 2 months ago

Hi @hossenlopp

We've been using fqm-execution's Calculator.calculate method with the above provided inputs / options that returns a measureReport.

The results we've been accessing have been located from the result of Calulator.calculate as result.results.detailedResults.stratifierResults which come in the shape of

{ "strataCode": "strata-1", "result": true, "strataId": "93f5f1c7-8638-40a4-a596-8b5831599209" }

Is there another way the results from stratification should be accessed?

In general in the detailed results the stratifications are treated as a "filter" to be applied to the population(s) they belong to. So they will be evaluated and be true or false regardless of results of the population(s) results. When creating a MeasureReport from the detailed results, the stratified results will have stratifier applied to the population(s) and if the patient isn't in a population, they will not count in that stratification. This may be what your implementation should look to doing if you are working from the detailed results.

With this in mind, if no association is provided or any association is provided, the stratification will still be evaluated independently of this. Is this intended?

I explored options that I believe were hinted at above.

What we use: calculate(measureBundle: fhir4.Bundle, patientBundles: fhir4.Bundle[], options: T, valueSetCache?: fhir4.ValueSet[]): Promise<CalculationOutput>;

other option 1: calculateIndividualMeasureReports(measureBundle: fhir4.Bundle, patientBundles: fhir4.Bundle[], options: CalculationOptions, valueSetCache?: fhir4.ValueSet[]): Promise;

other option 2: calculateMeasureReports(measureBundle: fhir4.Bundle, patientBundles: fhir4.Bundle[], options: CalculationOptions, valueSetCache?: fhir4.ValueSet[]): Promise;

in spite of seemingly having the same input signatures, and providing the same inputs as calculate, both other methods appear throw errors when being used with same values An error occurred in FQM-Execution TypeError: Cannot read properties of undefined (reading 'text') at MeasureReportBuilder.js:219:1

Am I doing something obviously wrong here?

The purpose of this investigation was to see how fqm-execution would be able to handle cardinality for stu-4, and if it's possible to use the tooling as it is now for those changes.

Would the advisory be to use the detailed result above and instead map the ultimate stratification display value?

Where we display true only if stratification = true and association population = true?

mcmcphillips commented 2 months ago

Would there be any additional guidance on how to get the other two functions that were hinted at here to work as expected?

Thanks for submitting this issue with most of the data we need. Just have one question, are you using the "detailed" output of fqm-execution or the MeasureReport output?

other option 1: calculateIndividualMeasureReports(measureBundle: fhir4.Bundle, patientBundles: fhir4.Bundle[], options: CalculationOptions, valueSetCache?: fhir4.ValueSet[]): Promise;

other option 2: calculateMeasureReports(measureBundle: fhir4.Bundle, patientBundles: fhir4.Bundle[], options: CalculationOptions, valueSetCache?: fhir4.ValueSet[]): Promise;

These two, while still expecting the same parameters, throw errors where calulate method does not.

elsaperelli commented 2 months ago

Hi @mcmcphillips! Regarding your experience with errors using calculateMeasureReports and calculateIndividualMeasureReports, we currently have a PR up to address these issues. The issue was with how older measures identified stratifiers, but that will be updated to properly identity stratifiers based on the newer measures. We estimate to have a release for this August 2 at the earliest.

JSRankins commented 2 months ago

@hossenlopp, does discussion at CQI this morning change the proposed solution above?

hossenlopp commented 2 months ago

@JSRankins, yes. Now that we have clarification on what appliesTo does and that it will continue to be in QMIG we are going to consider adding results to the detailed output that base the stratifier on the population it applies to.

JSRankins commented 2 months ago

@JSRankins, yes. Now that we have clarification on what appliesTo does and that it will continue to be in QMIG we are going to consider adding results to the detailed output that base the stratifier on the population it applies to.

Awesome! Thank you for the quick response.

hossenlopp commented 1 month ago

As of fqm-execution v1.5.0 the appliesResult is included for stratification. This result will only be true if the associated population is true and the result of stratifer criteria is true.

gregory-akins commented 1 month ago

As of fqm-execution v1.5.0 the appliesResult is included for stratification. This result will only be true if the associated population is true and the result of stratifer criteria is true.

@hossenlopp I just pulled the latest into MADiE and am still seeing incorrect results

Should I start another ticket?

elsaperelli commented 1 month ago

Hi @gregory-akins ! Regarding the incorrect results you are seeing, if that in reference to testing with the measure and patient bundle that is attached to this issue or another measure bundle and/or patient bundle? Thank you!

gregory-akins commented 1 month ago

Hi @gregory-akins ! Regarding the incorrect results you are seeing, if that in reference to testing with the measure and patient bundle that is attached to this issue or another measure bundle and/or patient bundle? Thank you!

I can upload the newest one; I believe it's the same.

valuesets.txt Patients.json Measure.json

elsaperelli commented 1 month ago

Thank you! After running detailed calculation with the provided measure and patient, it looks like the results are correct, so I want to make sure our stratification documentation here makes sense. Our intention with result on the stratifierResult was to keep that raw value the same. In this case, the stratifierResults result is true because the cql for Stratification1 is true. However, the population result for the Initial Population is false. This is why we now include appliesResult and it evaluates to false. Attached are the detailedResults for this.

image

gregory-akins commented 1 month ago

Ah.. that's helpful I wasn't clear on what appliesResult was

Thanks!