Stream: implementers
Topic: Indicating observation not performed for a reason
Floyd Eisenberg (Oct 15 2019 at 15:36):
Seeking guidance for most effective way to indicate that an observation intentionally did not occur with a reason it was not done and when that information was documented. Current R4 Observation modeling uses a specific Observation.status value set which is different from the Event.status value set. The Event.status value set includes "not-done" as an option but Observation.status value set does not. Resources such as Procedure allow a .status = not-done and statusReason for indication of rationale for not performing the procedure. For the QI-Core implementation guide ballot reconciliation I am seeking advice about whether to consider Observation with an extension to address not-done status or if Procedure.status is more appropriate. Thanks, in advance for suggestions.
Eric Haas (Oct 15 2019 at 15:41):
Use the standard extension: http://hl7.org/fhir/StructureDefinition/event-statusReason
Eric Haas (Oct 15 2019 at 15:43):
for an observation status of:
cancelled 'The observation is unavailable because the measurement was not started or not completed (also sometimes called "aborted")'
Eric Haas (Oct 15 2019 at 15:45):
Somewhere Rob H or I have a concept mapping to the event statuses.
Floyd Eisenberg (Oct 15 2019 at 22:52):
cancelled doesn't fit our use case. It assumes the activity was started and then something changed to cancel it. Our use case is a decision not to do something that might otherwise be expected. Clinicians don't start and then cancel. There needs to be a way to indicate "I don't want to do this expected activity" -- and we have used "resource".status = not-done for this purpose, but Observation has a specific status value set that does not include not-done. So our use case is not met. Hence the question if Procedure is a better way to indicate not-done (I.e., the lab test wasn't done - it wasn't cancelled, it wasn't done in the first place for a reason). Does that help with the request? Event.status would help if Observation.status used event.status but it doesn't.
Floyd Eisenberg (Oct 15 2019 at 22:54):
So we have 2 options - create an extension to use event.status (perhaps this is actually a profile Observation.statusAvoided with event.statusReason) but that seems excessive perhaps, or to consider use of Procedure instead when "not-done"
Eric Haas (Oct 15 2019 at 23:44):
What about using the terminology
Eric Haas (Oct 15 2019 at 23:45):
This sound like cda negation indicator stuff which we don’t really do in fhir
Eric Haas (Oct 15 2019 at 23:46):
Actually I take that back
Eric Haas (Oct 15 2019 at 23:47):
We use data absent reason to say not done
Lloyd McKenzie (Oct 16 2019 at 01:23):
The pattern is to have a specific status for "not done" (as distinct from cancelled). Is there a reason OO decided not to follow that route? Is that something that could be considered for R5?
Floyd Eisenberg (Oct 16 2019 at 12:36):
Yes, Observation.dataAbsentReason was my first thought but the value set, though extensible seems to suggest more operational reasons for lack of results - http://hl7.org/fhir/r4/valueset-data-absent-reason.html**http://hl7.org/fhir/r4/valueset-data-absent-reason.html. And the only available timings that might fit are (a) Observation.issued, which indicates when the version of the observation was made available to providers and (b) Observation.effective[x] the time or time-period the observed value is asserted as being true. Timing for the decision or recording of decision not to perform the observation is not covered by strict interpretation of .effective or .issued. So the current question in R4 is whether we can "extend" the meaning by using .dataAbsentReason and .effective[x] to indicate such an intended negation. That would mean we need a status that works (and there is no applicable status in the required value set for observation. OR we could consider using Procedure.status = not-done to address such intentional negation. Considerations for R5 are helpful but we need to address the issue in R4 as well. Perhaps another alternative might be ServiceRequest since the concept might be considered a request/determination not to do something. Thoughts?
Jay Lyle (Oct 16 2019 at 15:16):
If you want to use Observation, cancelled looks like the only option.
'cancelled' means "The observation is unavailable because the measurement was not started or not completed (also sometimes called "aborted")."
It seems to _include_ the semantics of aborted (started, not finished), but also to include never started. So it seems OK to me, if not perfect. But if the potential implication that an observation was intended before being cancelled is untenable, then you don't want Observation; you want Procedure with a "not done."
I seem to recall being told that a required binding means no DAR allowed. And Observation is normative, so adding a value to R5 will be difficult.
Semantically, I think Procedure works better. Your primary assertion is that the act was not done, the absence of the result is incidental.
Eric Haas (Oct 16 2019 at 19:49):
I seem to recall being told that a required binding means no DAR allowed. And Observation is normative, so adding a value to R5 will be difficult.
is not correct here:
there is a DAR element: Observation.dataAbsentReason
so code = X
value is absent ( not populated)
DAR = not done, patient refused, dog ate it etc,
Lloyd - No
Lloyd McKenzie (Oct 16 2019 at 20:23):
@Eric Haas Was that 'no' a response to the "is there a reason?" question or the "could we change it in R5?" question?
Eric Haas (Oct 17 2019 at 01:32):
These statuses have been discussed ad nauseam and the burden lies with anybody requesting the change to convince the committee to change. So the starting point is no.
Floyd Eisenberg (Oct 17 2019 at 15:40):
What I take from this discussion: DataAbsentReason might work for why observation did not occur. However, our eCQM expressions require a status and there is no acceptable Observation.status required code that works. If there is a dataAbsentReason, it may be due to a status = cancelled or something else (but cancelled doesn't fit the eCQM use case). Hence, since the workflow probably works better as a Procedure.status = not-done since the procedure to perform the observation did not happen (per Jay's comment and my thoughts as well). Thanks for this feedback.
Hans Buitendijk (Oct 17 2019 at 16:40):
My take could get challenging, as it is based on actual data out there. We need to allow for the use of:
- Observation.valueCodeableConcept = Not Done. Examples would be where various assessments are valued Not performed | 262008008 | 2.16.840.1.113883.6.96
- Observation.dataAbsentReason = not-performed
- Obsevation.status = not-done
Updates would need to be made to status value set to include not-done. We should not remove cancelled as there is a nuance between not-done and cancelled. Plus Observation is normative.
However, we should not start to use a Procedure to record when something was not done, but Observation when it was done. That will get very confusing.
Eric Haas (Oct 17 2019 at 17:54):
is the actual data out there really Observation.status = not-done? because in the HL7 world there has never been a status of not-done for Observation not table 85 or 123 in V2 nor in CCDA. (2.16.840.1.113883.5.14)
the first two are typically how it is stated. within the name value pair paradigm.
Eric Haas (Oct 17 2019 at 17:56):
And introducing a 3rd way will as Hans indicated "get challenging" for implementers
Floyd Eisenberg (Oct 18 2019 at 15:23):
Hans - I like your suggestion but, like Eric, I don't know where to find Observation.valueCodeableConcept = Not Done. Further Observation.dataAbsentReason allows an eCQM author to create a specific value set (I.e., the existing FHIR value set is not Required) - please confirm. And what would be the timing - Observation.issued? I think what I'm seeing is that we might be able to create an extension in QI-Core to use a different value set (I.e., the same as what you have plus "not-done") - Does that work?
Eric Haas (Oct 19 2019 at 01:41):
In scenarios 1 and 2 above the dateTime elements 'issued' aka when the observation of not done was posted and effective aka the clnically relevent dateTime of when the observation was (supposed to be made) are no different than if the observation was made.
Eric Haas (Oct 19 2019 at 01:41):
... and the status for observation would be the same
Eric Haas (Oct 19 2019 at 01:44):
In scenario three which I am against. the dateTime elements would be the same.... I am not sure why QI-Core would want to carve out its own path. Can you present a real life simple example to illustrate what you want exactly?
Eric Haas (Oct 19 2019 at 03:07):
to document a reason in order to meet the intent:
- for scenario 1 above the
note
element would contain the reason. - for scenario 2 above the
valueAbsentReason
element would contain the reason.
Floyd Eisenberg (Oct 21 2019 at 22:12):
Eric, I'm having trouble understanding scenario 1 and scenario 2 - what are the 2 scenarios you reference? My concern is about something that didn't happen "on purpose" for a reason. So I think that means: status = final (the fact it isn't happening is final); dataAbsentReason is valued with a direct reference code or a value set to allow a specific instance specify what reasons are acceptable; and timing = observation.issued - because that is when the reason not done is valued. Will that work? Example - asthma risk assessment was expected at the visit but it was not performed because the patient was in the midst of an asthma attack requiring acute treatment. So Observation.status = final (for that encounter), Observation.dataAbsentReason = Medical Reason, Observation.issued = dateTime reason was entered.
Eric Haas (Oct 22 2019 at 01:18):
From Hans' Post:
- Observation.valueCodeableConcept = Not Done. Examples would be where various assessments are valued Not performed | 262008008 | 2.16.840.1.113883.6.96
- Observation.dataAbsentReason = not-performed
Floyd Eisenberg (Oct 22 2019 at 13:19):
Thanks - but Hans' comment dataAbsentReason = not-performed is not sufficient. We actually need the reason, we already know it isn't performed by the attribute. I think my options still work:
Observation.dataAbsentReason = [value set] or [direct reference code]
Observation.status = final
Observation.issued = dateTime (I.e. time of the entry of the dataAbsentReason since the observation did not occur)
Eric Haas (Oct 22 2019 at 15:37):
As I stated above:
to document a reason in order to meet the intent:
for scenario 1 above the note element would contain the reason.
for scenario 2 above the valueAbsentReason element could contain the reason. and the note element would contain the reason. too
Floyd Eisenberg (Oct 24 2019 at 12:37):
I understand the response but it doesn't match the use case. We need to be able to state (1) not done (the scenario 1) and (2) a reason it wasn't done. However, the reason cannot be a "note" it must meet specific allowable coded reasons. And the Observation.dataAbsentReason value set is consistent with why a result wasn't published by a laboratory, but it does not fit with reasons that a clinician or a patient failed to perform the observation (I.e., a medical consideration or a patient refusal). VSAC contains 51 value sets created to address reasons for not performed an activity just related to medical reason (all coded and that doesn't include patient reasons). While there are many duplicates in that set, it does provide the use case.
Eric Haas (Oct 24 2019 at 18:31):
Observation.dataAbsentReason value set . could all those 51 valuesets be additional codings to 'not-performed' providing more granular details.
also I think that the note element of type Annotations allow for codes. too. since the markdown datatype is a string specialization and you can bind valuesets to strings.
The instance carries a string. In some cases, applications may wish to control the set of valid strings for a particular element, so the string value can be treated as a coded element (like code)
@Grahame Grieve verifying that markdown can be treated as codes as well?
Grahame Grieve (Oct 24 2019 at 18:32):
we haven't said so
Robert McClure (Oct 27 2019 at 16:57):
@Eric Haas & @Floyd Eisenberg Sorry, for a recap request, but can we reestablish where the scenario below is problematic?
Scenario:
Where there is an observation (and I think this is also true for procedure) that is not done/performed and therefore does not have "typical" observation.value, we want to say this is the FINAL status of that observation, and the reason it was not done must be a coded concept.
Approach:
observation.status = Final
observation.valueCodableConcept = Not performed | 262008008 | 2.16.840.1.113883.6.96 (or some such, but I'd like this)
observation.dataAbsentReason = binding is currently extensible DataAbsentReason so for an eCQM profile we bind to value set that we need to cover our QM uses, but if someone want to send something additional, they need to create a new value set with the additional codes they need.
Now I understand that you want to scope all the specifics we need under the existing not-performed concept in DAR, but in this case, at least, that is not the correct semantics, IMO. For me, the current semantics are system focused and not clinical user focused.
Floyd Eisenberg (Oct 27 2019 at 17:49):
@Robert McClure & @Eric Haas - Modification to your scenario with respect to what is problematic:
Scenario:
Where there is an observation that is not done/performed, there is an observation.code (type of observation/code) and there is no observation.value (I.e., there is no actual result). We still need to indicate a status for which the most appropriate status value = final. And, the reason the observation was not performed must be a coded concept that is different than the existing dataAbsentReason value set (extensibly bound) since that existing value set as you noted is system-focused and not clinical user (or patient) focused. So the need is to address QDM's negation rationale consisting of three "components":
- Observation.status = final
- Observation.issued (the time the reason not performed is entered)
- Some way of indicating the reason the observation action did not occur (clinical or patient reason)
So, Rob, from your comments, I take 2 notes:
1) dataAbsentReason may be inadequate and perhaps we need a specific extension for notDoneReason with the clinically-focused value set we discussed (unless we can shoe-horn in re-use of dataAbsentReason
2) Perhaps we also need to specify Observation.value[x] with "not performed" - however, I my expectation is that no observation.value exists and that implementers will have more trouble forcing a value into the Observation.value[x] than just using a CQL expression indicating "not exists Observation.value" - If we need a direct reference code value, I think we want something like "intentionally not performed" - just "not performed" is too generic. My preference is to avoid insistence of a value for Observation.value.
2.a.) If we must value the Observation.value, we would need to value the "result" for all of the QI-Core/FHIR resource profiles that enable "not performed for reason" - that includes MedicationRequest, MedicationAdministered, Observation, Procedure, Communication, ServiceRequest, Communication. Are you sure we need to do that?
Grahame Grieve (Oct 27 2019 at 22:17):
I don't see any reason from this thread to think that we want to populate Observation.value when there is no value. The most obvious approach is to define a new value set with extensions to the DAR value set and use those.
Eric Haas (Oct 28 2019 at 18:44):
I happens in the real world as Hans stated above that users stick "not performed' in observation values whether is ideal or not. So I don't it can be ignored.
Floyd Eisenberg (Oct 28 2019 at 20:09):
@Eric, I appreciate implementers may place "not performed" in the observation.value but for our use case we don't expect a real result. Hence, whether it is empty or it includes "not performed" there is no difference. I think that specifically looking for a value = not performed is highly problematic because it will often be missing.
Eric Haas (Oct 28 2019 at 21:45):
Can you clarify what the use case is? I have been under the assumption that use case was to identify and formulate some guidance around how represent "not done" Observations in FHIR for QI Core so that the QDM criteria are met in a machine readable way.
Grahame Grieve (Oct 28 2019 at 22:22):
It happens in the real world as Hans stated above that users stick "not performed' in observation values whether is ideal or not. So I don't it can be ignored.
Sure. but let's not encourage that at all
Floyd Eisenberg (Oct 29 2019 at 13:18):
@Eric Haas The use case is to represent "not done for a reason" observations in FHIR for QI-Core so that QDM criteria are met in a machine readable way. So if there is a reason why an observation did not occur, there should not be a populated value field. If it is populated with "not done" (which I agree with Grahame should not be encouraged), that doesn't matter. We do want to know there is not a "valid" result in the value field and CQL can indicate not exists value = "expected response (I.e., specific code from a measure-defined value set, or numerical value with UCUM units)"
Last updated: Apr 12 2022 at 19:14 UTC