openmrs-core icon indicating copy to clipboard operation
openmrs-core copied to clipboard

TRUNK-6245: Age sensitive concept ranges

Open dicksonmulli opened this issue 1 year ago • 41 comments

TRUNK-JiraIssueNumber: https://openmrs.atlassian.net/browse/TRUNK-6245

Description of what I changed

  • Adding a concept-reference-range entity to capture concept ranges for different factors e.g. Age, Gender
  • Adding utility class to evaluate if patients' age meet criteria as described in criteria column in concept-reference-range
  • Liquibase changesets to create concept-reference-range table
  • Unit tests

Issue I worked on

see https://issues.openmrs.org/browse/TRUNK-6245

Checklist: I completed these to help reviewers :)

  • [x] My IDE is configured to follow the code style of this project.

    No? Unsure? -> configure your IDE, format the code and add the changes with git add . && git commit --amend

  • [x] I have added tests to cover my changes. (If you refactored existing code that was well tested you do not have to add tests)

    No? -> write tests and add them to this commit git add . && git commit --amend

  • [x] I ran mvn clean package right before creating this pull request and added all formatting changes to my commit.

    No? -> execute above command

  • [x] All new and existing tests passed.

    No? -> figure out why and add the fix to your commit. It is your responsibility to make sure your code works.

  • [x] My pull request is based on the latest changes of the master branch.

    No? Unsure? -> execute command git pull --rebase upstream master

dicksonmulli avatar Jul 10 '24 15:07 dicksonmulli

I have added a few more comments. Liquibase changes should be in liquibase-update-to-latest-2.7.x.xml

dkayiwa avatar Jul 11 '24 07:07 dkayiwa

@dicksonmulli can you look at the merge conflicts?

dkayiwa avatar Jul 27 '24 17:07 dkayiwa

FYI @mogoodrich & @mseaton - this will be important for your work in MCOE for neonatal vital sign ranges etc.

gracepotma avatar Jul 30 '24 14:07 gracepotma

Did you attempt looking at the failing tests?

dkayiwa avatar Aug 10 '24 21:08 dkayiwa

@dicksonmulli can we also have a method that clients like this can use? https://github.com/openmrs/openmrs-module-legacyui/blob/1.16.0/omod/src/main/java/org/openmrs/web/dwr/DWRConceptService.java#L471-L475

dkayiwa avatar Aug 13 '24 11:08 dkayiwa

@dicksonmulli can we also have a method that clients like this can use? https://github.com/openmrs/openmrs-module-legacyui/blob/1.16.0/omod/src/main/java/org/openmrs/web/dwr/DWRConceptService.java#L471-L475

What kind of a method? Kindly explain

dicksonmulli avatar Aug 13 '24 13:08 dicksonmulli

What kind of a method? Kindly explain

A method like public boolean isValidNumericValue(Float value, Integer conceptId, Integer patientId)

dkayiwa avatar Aug 13 '24 13:08 dkayiwa

A method like public String getErrorMessageIfInValidNumericValue(Float value, Integer conceptId, Integer patientId) would be even more useful because it returns the exact error message which includes the expected range. For instance, an error message like Invalid value for numeric is not as useful to the end user as something like Invalid value for numeric. Expected a value between 0 and 250

dkayiwa avatar Aug 13 '24 13:08 dkayiwa

A method like public String getErrorMessageIfInValidNumericValue(Float value, Integer conceptId, Integer patientId) would be even more useful because it returns the exact error message which includes the expected range. For instance, an error message like Invalid value for numeric is not as useful to the end user as something like Invalid value for numeric. Expected a value between 0 and 250

I understand. However, it would be great to have the business logic around it so that I can understand it end to end. If this requires a separate ticket it would be great to have a description. Thank you.

dicksonmulli avatar Aug 13 '24 13:08 dicksonmulli

It is part of the API that comes with this functionality. So it is part of this pull request.

dkayiwa avatar Aug 13 '24 13:08 dkayiwa

How do we deal with cases where a concept numeric already has absolute high and low values set, but also has reference ranges? Do we ignore the former? Do we use both?

dkayiwa avatar Aug 15 '24 12:08 dkayiwa

How do we deal with cases where a concept numeric already has absolute high and low values set, but also has reference ranges? Do we ignore the former? Do we use both?

@dicksonmulli did you see the above question?

dkayiwa avatar Aug 15 '24 23:08 dkayiwa

How do we deal with cases where a concept numeric already has absolute high and low values set, but also has reference ranges? Do we ignore the former? Do we use both?

@dkayiwa do you mean in case when we want to update concept numeric?

dicksonmulli avatar Aug 16 '24 09:08 dicksonmulli

No. What i mean is that in addition to the concept reference ranges, the concept numeric itself may have values already set as you can see here: https://demo.openmrs.org/openmrs/dictionary/concept.htm?conceptId=5089

dkayiwa avatar Aug 16 '24 09:08 dkayiwa

No. What i mean is that in addition to the concept reference ranges, the concept numeric itself may have values already set as you can see here: https://demo.openmrs.org/openmrs/dictionary/concept.htm?conceptId=5089

Right. What we discussed earlier with you is to keep both concept numeric & reference range values until concept reference range is stable and adopted. There after we can use concept reference ranges. Also in terms of validation, we can still use both.

dicksonmulli avatar Aug 16 '24 09:08 dicksonmulli

So what happens when one has both set?

dkayiwa avatar Aug 16 '24 09:08 dkayiwa

So what happens when one has both set?

I have tested a scenario when both are set and it's working as expected. Concept Numeric values are evaluated first then concept reference range values. Ideally reference range bounds will be strict but the good thing is that they will lie in between concept numeric bounds. Do we expect a different scenario?

dicksonmulli avatar Aug 16 '24 09:08 dicksonmulli

I never tested it. Was just thinking about it.

dkayiwa avatar Aug 16 '24 09:08 dkayiwa

@dkayiwa is there anything else pending for this PR?

dicksonmulli avatar Aug 16 '24 10:08 dicksonmulli

Work on the documentation as i continue reviewing.

dkayiwa avatar Aug 16 '24 10:08 dkayiwa

@dicksonmulli if there are no reference ranges defined, but the concept numeric record has values, do we end up using these values to create an obs reference range?

dkayiwa avatar Aug 16 '24 11:08 dkayiwa

@dicksonmulli if there are no reference ranges defined, but the concept numeric record has values, do we end up using these values to create an obs reference range?

At the moment no. We only create obs reference range from concept reference ranges

dicksonmulli avatar Aug 16 '24 11:08 dicksonmulli

Work on the documentation as i continue reviewing.

Kindly share a link page where we can add this documentation.

dicksonmulli avatar Aug 16 '24 11:08 dicksonmulli

At the moment no. We only create obs reference range from concept reference ranges

Can we do this too?

dkayiwa avatar Aug 16 '24 11:08 dkayiwa

Kindly share a link page where we can add this documentation.

Add it as one of the child pages here: https://openmrs.atlassian.net/wiki/spaces/docs/pages/25475738/Administering+Concepts

dkayiwa avatar Aug 16 '24 11:08 dkayiwa

I have tested a scenario when both are set and it's working as expected. Concept Numeric values are evaluated first then concept reference range values.

This may be an issue for some of the use-cases here. Specifically, reference ranges for results on children can be substantially different from the ranges for adults, and I'm worried how this interacts with the rule that we use the most limited scope of all reference ranges that apply. For example, fasting blood glucose reference ranges something look like this:

Infant:
  Normal: 40-90 mg/dL
  Critical < 40 mg/dL or > 300 mg/dL
< 2 years:
  Normal: 60-100 mg/dL
  Critical < 40 mg/dL or > 300 mg/dL
> 2 years: 
  Normal: 70-110 mg/dL
  Critical: < 54 or > 400 mg/dL

The issue here is that the concept reference ranges (where they exist) are usually defined as an adult and there's a small range here (40 <= x < 54) where the adult reference ranges would suggest a critical value, but which is within the normal range. Is this similar to the scenario you tested?

(This is not a concern with the evaluated reference ranges, since, of course, the rules wouldn't match both Infant and Adult for the same patient)

ibacher avatar Aug 16 '24 12:08 ibacher

This may be an issue for some of the use-cases here. Specifically, reference ranges for results on children can be substantially different from the ranges for adults, and I'm worried how this interacts with the rule that we use the most limited scope of all reference ranges that apply. For example, fasting blood glucose reference ranges something look like this:

Infant:
  Normal: 40-90 mg/dL
  Critical < 40 mg/dL or > 300 mg/dL
< 2 years:
  Normal: 60-100 mg/dL
  Critical < 40 mg/dL or > 300 mg/dL
> 2 years: 
  Normal: 70-110 mg/dL
  Critical: < 54 or > 400 mg/dL

The issue here is that the concept reference ranges (where they exist) are usually defined as an adult and there's a small range here (40 <= x < 54) where the adult reference ranges would suggest a critical value, but which is within the normal range. Is this similar to the scenario you tested?

(This is not a concern with the evaluated reference ranges, since, of course, the rules wouldn't match both Infant and Adult for the same patient)

@ibacher Could you elaborate more on the scenario. You mentioned This is not a concern with the evaluated reference ranges so in which occasion do we expect this to happen? Concept reference ranges will now have criteria to help pick the right range for the patient.

dicksonmulli avatar Aug 16 '24 13:08 dicksonmulli

@dicksonmulli I'm thinking about the scenario where we already have a reference range defined on the ConceptNumeric, but then also have a series of the new ConceptReferenceRange classes defined for the same concept, in which case the reference range on the ConceptNumeric is (for historical reasons) most likely to be the adult reference range.

Or am I misunderstanding how things work?

ibacher avatar Aug 16 '24 14:08 ibacher

@dicksonmulli I'm thinking about the scenario where we already have a reference range defined on the ConceptNumeric, but then also have a series of the new ConceptReferenceRange classes defined for the same concept, in which case the reference range on the ConceptNumeric is (for historical reasons) most likely to be the adult reference range.

I see. So which means if no conceptReferenceRange evaluated to true, and we proceed to set obsReferenceRange values from ConceptNumeric values, then we might end up setting the wrong values to a certain patient, right? cc @dkayiwa

dicksonmulli avatar Aug 16 '24 14:08 dicksonmulli

Well, I think as long as we ignore the ConceptNumeric range if any ConceptReferenceRange evaluates to true (i.e., we assume that those reference ranges are correct), then we avoid any issues. We could still end up setting the wrong values for an observation, but at that point it's a data issue and not a code issue.

ibacher avatar Aug 16 '24 16:08 ibacher