TRUNK-6245: Age sensitive concept ranges
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
criteriacolumn 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 packageright 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
I have added a few more comments. Liquibase changes should be in liquibase-update-to-latest-2.7.x.xml
@dicksonmulli can you look at the merge conflicts?
FYI @mogoodrich & @mseaton - this will be important for your work in MCOE for neonatal vital sign ranges etc.
Did you attempt looking at the failing tests?
@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
@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
What kind of a method? Kindly explain
A method like public boolean isValidNumericValue(Float value, Integer conceptId, Integer patientId)
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
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 likeInvalid value for numericis not as useful to the end user as something likeInvalid 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.
It is part of the API that comes with this functionality. So it is part of this pull request.
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?
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?
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?
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
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.
So what happens when one has both set?
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?
I never tested it. Was just thinking about it.
@dkayiwa is there anything else pending for this PR?
Work on the documentation as i continue reviewing.
@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?
@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
Work on the documentation as i continue reviewing.
Kindly share a link page where we can add this documentation.
At the moment no. We only create obs reference range from concept reference ranges
Can we do this too?
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
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)
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/dLThe 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 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?
@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
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.