FHIR Chat · Pathology Lab Reports – Dynamic Function Tests / Timed Tests · implementers

Stream: implementers

Topic: Pathology Lab Reports – Dynamic Function Tests / Timed Tests


view this post on Zulip Phil Brennan (Feb 03 2021 at 13:44):

I am looking at options for supporting a type of pathology lab test known as a Dynamic Function Test (also sometimes referred to as a Timed Test). This is where a series of specimens are collected at defined relative time points before and after an intervention to assess the response to that intervention. The same type of test is performed against each collected specimen and the results are reported as a set. A simple example of a Dynamic Function Test is a glucose tolerance test, as illustrated in this example test report fragment:

GTT_Report.png

For a Glucose Tolerance Test an initial glucose level is measured (at O Min) and the patient is then asked to drink a glucose drink. Further specimens are then taken and the level of glucose measured. Other lab tests that are commonly used as part of a Dynamic Function Test include Growth Hormone, Cortisol and Thyrotropin Releasing Hormone tests.

To group the results I am planning to use a parent Observation with a set of child Observations (similar to the method you would use for grouping a set of individual test results that form part of a test panel or battery such as a Full Blood Count). The value set for observation relationship types (http://hl7.org/fhir/STU3/valueset-observation-relationshiptypes.html) includes an entry for ‘sequel-to’. This looks like the best option for linking the parent and child Observations (the specification mentions that ‘sequel-to’ can be used for timed tests such as a Glucose Tolerance Test). Each Observation would reference the associated Specimen. The Observations would be linked to an instance of a DiagnosticReport.

The question is how best to support the relative time interval associated with each Observation (e.g. 0 Min, 1 Hr, 2 Hr). One option would be to encode the time interval as part of the observed entity (i.e. test name). So we would have separate Observation.code descriptions (and codes) such as “0 minute glucose level”, “60 minute glucose level” etc. Obviously this approach isn’t particularly flexible.

Another option would be to carry the relative time interval as part of each Observation. However I can’t see an obvious way of doing this. We are planning to use Observation.effective with a data type of dateTime to record the actual time of the observation (e.g. 2021-02-07T13:28) but there does not seem to be a data type that supports the concept of a relative time interval. Our work is currently based on STU3. I’m aware that R4 has introduced an additional data type of Timing for Observation.effective but that doesn’t seem to meet the requirement.

Any ideas/suggestions would be very welcome.

view this post on Zulip Abel Enthoven (Feb 03 2021 at 16:23):

Hi @Phil Brennan would it be an option to use Observation.component for this? The observation would then have 2 components: 1 for the value and 1 for the relative time. The time could then be a Quantity with UCUM unit 'min' (for minutes) or 'h' (for hour), combined with a code identifying the type of component. This is similar to the way you would record a blood pressure for example

view this post on Zulip Lloyd McKenzie (Feb 03 2021 at 17:27):

Observation.component would not be legitimate as it's different specimens taken at different times. Typically I'd expect the linkage between the grouping Observation and the children to be with hasMember. The "sequel to" could be used to link the children. I.e. the second could point to the first and the third could point to the second.

view this post on Zulip Abel Enthoven (Feb 04 2021 at 10:26):

I was referring to an Observation with 2 components (value and relative time) per specimen @Lloyd McKenzie , thought that was the question. The hasMember relationship is indeed preferable for the group as a whole

view this post on Zulip Lloyd McKenzie (Feb 04 2021 at 15:18):

If the Observation.code didn't tell you the measurement time offset, you could convey this with a component. The value for the glucose level would still go in Observation.value though, not in a component.

view this post on Zulip Eric Haas (Feb 04 2021 at 15:25):

Why is the code not good enough?

view this post on Zulip Eric Haas (Feb 04 2021 at 15:26):

As I understand it there are standard protocols for these tests and thus loinc codes

view this post on Zulip Lloyd McKenzie (Feb 04 2021 at 15:37):

If you're using LOINC, code should be good enough. I wasn't making that presumption and was indicating when Abel's approach could work (with a bit of modification).

view this post on Zulip Phil Brennan (Feb 04 2021 at 16:45):

Many thanks everyone for your input and suggestions. We are using SNOMED instead of LOINC but could follow a similar approach and encode the time interval as part of the test. So we would have separate SNOMED term descriptions/codes such as ‘30 minute serum glucose level’, ‘60 minute serum glucose level’ etc.

We have used this type of pre-coordinated approach before but to allow greater flexibility we are considering carrying the time interval element outside of the test name and in FHIR.

@Abel Enthoven the idea of using a component to carry the time interval looks interesting, thanks for that. Also thanks @Lloyd McKenzie for clarifying use of ‘has-member’ and ‘sequel-to’.

view this post on Zulip Eric Haas (Feb 04 2021 at 19:16):

why the pre-coordinated approach less flexible exactly?

view this post on Zulip Phil Brennan (Feb 08 2021 at 15:55):

Hi @Eric Haas. Apologies for the delay in replying. The pre-coordinated approach is less flexible in that if a lab has a requirement to use a time interval that has not already been defined as part of an existing test result name, this would necessitate the creation of a new test description/code e.g. ‘300 minute serum glucose level’. Carrying the time interval elsewhere in FHIR would mean we could use a more generic test name of ‘serum glucose level’. This situation is more complicated for us because we are developing a nationally defined set of SNOMED CT based test names and codes. Any additions or changes to those test names would be managed and distributed at a national level rather than locally.

view this post on Zulip Lloyd McKenzie (Feb 08 2021 at 16:49):

Note that the tradeoff is you can no longer query and trend based on the specific code. If you have a different code per time-interval, you can trend the 60 minute measures for the last 3 years. If time-interval is a component, then you're going to get a whole lot of glucose levels that aren't comparable

view this post on Zulip Lin Zhang (Feb 08 2021 at 23:29):

Using SCT for encoding lab tests is not a good practice.

view this post on Zulip Lloyd McKenzie (Feb 08 2021 at 23:56):

It depends on the country somewhat. In the UK it's mandated. In the US, LOINC is mandated, at least for systems bound by US Core. Some countries might not use either.

view this post on Zulip Lin Zhang (Feb 09 2021 at 00:30):

@Lloyd McKenzie Got it. Thanks.

view this post on Zulip Phil Brennan (Feb 09 2021 at 16:36):

Thanks @Lloyd McKenzie and @Lin Zhang. I’m working on a UK based project so yes, SNOMED is the mandated coding scheme for terminology. Even though we are not using LOINC, it’s interesting to note how it supports Dynamic Function Tests / Timed Tests. In LOINC, the time interval is defined in the Challenge subpart within the Component/Analyte e.g. LOINC 51597-3 — Glucose [Moles/volume] in Serum or Plasma --1 hour post 75 g glucose PO. This is like the proposed pre-coordinated approach using SNOMED that I outlined above.

Lloyd, thanks for highlighting the downside of using the component as an option for carrying the time interval (rather than embedding it in the test name). I think that would be a problem for us. As well as being able to query on lab test usage, a key requirement is for any consuming system to be able to easily process and render the fully qualified test results for each time interval, for example 60 min: glucose 9.4 mmol/L, 120 min: glucose 9.1 mmol/L etc.

I’m guessing we would have the same issue if we carried the time interval component elsewhere in FHIR? For example, it could be argued that the time interval is actually an attribute of Specimen – something like ‘planned collection time’ (supported via a local extension) with a suitable value and unit of measure e.g. 60 min, 120 min etc.

Either way, it’s starting to sound like a post-coordinated approach would be more difficult to implement than the pre-coordinated method of embedding the time interval in the test name.

view this post on Zulip Lloyd McKenzie (Feb 09 2021 at 16:51):

There's an extension that allows expressing a time as an offset from another time. If you had a custom search criteria on that - or for that matter, if you used a search criteria on your component offset value, you might be able to filter. However, it would be harder and probably not as well-supported. You also wouldn't be able to do combined code + value searches which are often helpful when chaining. So there are certainly some benefits to post-coordinating - at least for 'typical' offsets.

view this post on Zulip Lin Zhang (Feb 09 2021 at 23:44):

Alternatively, post-coordinating would need a formal language such as the SNOMED CT Query Language and the CodeSystem as a formal ontology.

view this post on Zulip Robin Bosman (Feb 19 2021 at 13:33):

We are actually also investigating this in Belgium and asking ourselves similar questions. To express laboratory tests in Belgium we use LOINC codes. For the moment I am looking into the use of extensions when 'attributes' (for example in dynamic function tests) need to be added to LOINC codes. Something like this:
"code" : {
"extension" : [
{
"url" : "https://www.ehealth.fgov.be/standards/fhir/StructureDefinition/be-ext-relative-time",
"valueQuantity" : {
"value" : 50,
"unit" : "m",
"system" : "http://unitsofmeasure.org",
"code" : "m"
}
}
],
"coding" : [
{
"system" : "http://loinc.org",
[...]

view this post on Zulip Lin Zhang (Feb 19 2021 at 13:44):

Both pre- and post-coordination representaions have their own pros and cons. And any terminlogy is unable to address all the coding requirements at any time.

view this post on Zulip Robin Bosman (Feb 22 2021 at 08:46):

Our approach is that in the big majority of cases we will use LOINC codes that have the specific time interval in their LOINC code.
However: we do want a national strategy how to deal with the few tests that remain that do not have their time interval in their code. Following the example given by @Phil Brennan and the comments made in this thread: the timeOffset extension does not seem to be the right approach as this is an extension on .component and a dynamic function test should not be structured in .component, right?

view this post on Zulip Lloyd McKenzie (Feb 22 2021 at 15:04):

The time offset would be a qualifier of the type of information being observed. As such, using Observation.component is completely appropriate. When you're qualifying the observation made or the result, Observation.component is a better way to convey the information than an extension because more systems will handle it. The disadvantages of having it in component (harder to query), wouldn't be any different for an extension.

view this post on Zulip Robin Bosman (Feb 26 2021 at 10:46):

Tx Lloyd, but if we would understand Observation.component as a way to use a qualifier on the type of information I feel that goes against the way it is actually now defined in the base resource. The Observation.component element is defined as "[...] component observations [...] Examples include systolic and diastolic component observations[...]" For me, that seems to be something entirely different from using Observation.component to qualify what is expressed in Observation.code. I do agree it makes sense to structure qualifiers like this but do we not introduce a risk here if sometimes Observation.component really is about actual observations (with the value in Observation.component.value[x] and sometimes it is only about qualifying Observation.code.
Maybe I am making it too complicated?

view this post on Zulip Lloyd McKenzie (Feb 26 2021 at 14:09):

It is different, but Observation.component is used for both purposes. The description does briefly mention its ability for component to be used for qualifiers, but doesn't provide as much description/example as should probably be there. @Eric Haas

view this post on Zulip Eric Haas (Feb 27 2021 at 00:45):

Using the q word was discouraged in earlier edits since it is a loaded term. maybe now lots more implementaton experience using components that way we can justify adding this language in?

@Rob Hausam ?

view this post on Zulip Rob Hausam (Feb 27 2021 at 04:18):

I've copied the relevant text describing Observation.component and the reference to "qualifying information" (see italicized text):

10.1.5.3.2 Observation.component
Observation.component is used for any supporting result that cannot reasonably be interpreted and used outside the scope of the Observation it is a component of. Component observations may make up the separate and individual parts of the observation or may provide qualifying information to Observation.code and may only be able to be understood in relation to the Observation.code (for example, see the $stats operation). Therefore all code-value and component.code-component.value pairs need to be taken into account to correctly understand the meaning of the observation. Components should only be used when there is only one method, one observation, one performer, one device, and one time. Some use cases for using this structure include:

  1. Observations that are commonly produced and interpreted together. For example, systolic and diastolic blood pressure are represented as a single Blood pressure panel.
  2. Assessment tool results that are commonly produced and interpreted together. For example, a newborn Apgar score that is a single Observation with five components.
  3. Representing multiple answers to a question (relationship and boundaries between Observation and Questionnaire/QuestionnaireResponse). For example, reporting the types of alcohol consumed by a patient

I think we have some potentially confusing and insufficient language here. The italicized text is the only place (I believe) where we say anything about using Observation.component as a "qualifier" for the base Observation.code. And if that is understood as we typically use the term "qualifier" in the terminology sense, that would contradict the text that follows which says "Components should only be used when there is only one method, one observation, one performer, one device, and one time", as that rule would not be true of a component observation which had the intent of "qualifying" (i.e. refining) the meaning of Observation.code and therefore also the interpretation of its associated Observation.value. So probably the use of the word "qualifying" may have been a less than optimal choice, as qualification or refinement in the terminology sense is probably not really what we meant, as I think the cited example of the $stats operation bears out. Notably with the $stats operation, there is no Observation.value. In that case, the Observation.code represents a base observation "type", but it is not an actual observation instance itself, and the "type" represented by Observation.code is further qualified/refined by Observation.component.code. The resulting component observation can only be understood in relation to Observation.code, and the only values for the observations in the operation result are represented in Observation.component.value. I think if we understand and use the idea of "qualifying" of a base observation by a component observation in this way, and only in this way, then it is a safe and in some cases useful thing to do. But the presence or absence of any component observation should never be considered to have any effect whatsoever on the interpretation and use of Observation.value (if the Observation.value exists). If think if we will agree on and stick to those rules, then this should be understandable and it all should work.

To be clear, understanding the rules in this way would preclude the suggestion that Lloyd made of conveying the measurement time offset using a component, If the offset wasn't included in Observation.code. But I think it should be the right way to go, for the reasons noted above. And if we are in or can reach agreement on this, then we should add some text to Observation.component (and possibly elsewhere) that clarifies it.

view this post on Zulip Lloyd McKenzie (Feb 27 2021 at 14:08):

@Rob Hausam If I want to capture cuff size for a blood pressure, or that it was post-exertion vs. resting, or that the susceptability test was for organism X, I'd expect all of those things to be captured as Observation.component. But we don't have any examples that call out that usage. Certainly the behavior for 'stats' is going to be different. If I invoke $stats, I'd want average systolic and diastolic, but unless consistent, I wouldn't want 'exertion' or cuff size to show up at all.

view this post on Zulip Rob Hausam (Feb 27 2021 at 16:41):

@Lloyd McKenzie I certainly understand why you and probably all of us would see Observation.component as a convenient way to record information for blood pressure cuff size, post-exertion vs. resting, susceptibility for organism X, and many other similar examples, and why we would like to be able to use it in that way (or we think that we would like that). But I think at least part of the reason that we don't have examples that call out those uses is because those uses violate our other stated rules on how component observations should be used (whether that's for good or bad reasons, we can decide). For the moment I'll focus on the blood pressure cuff size example (we can look at the others, too). Recording the cuff size (if that is done as an observation rather than as an attribute of the device) is an observation that is made on the device that is being used to make the measurement on the patient (I think the Observation.focus would refer to the blood pressure cuff device - and there is no Observation.component.focus). That observation would not be a "supporting result that cannot reasonably be interpreted and used outside the scope of the Observation it is a component of", and it also doesn't meet the rule of "only one method, one observation, one performer, one device, and one time". Neither of those "rules" are stated using conformance language (they say "is used" and "should only be used", rather than using "MUST" or "SHOULD") - so maybe they're actually only "suggestions" and we don't have to follow them. But they are fairly strong and clear statements of the intent, and if we are going to allow and recommend using Observation.component for recording blood pressure cuff size and the other examples that were cited (and anything similar), then at the least we should revise that language (the Observation resource is normative, but presumably loosening those "rules" is something that we could consider doing). My preference at the moment is to retain the original intent of the use of Observation.component and to further clarify the language and conformance expectations around that.

view this post on Zulip Lloyd McKenzie (Feb 27 2021 at 16:46):

@Rob Hausam I agree that cuff size is ideally captured as 'device'. However, there are a lot of systems that won't understand the difference between 'cuff size' and 'exertion level' and 'body position' - to them, they're all just 'qualifiers'. I think it's fair to say that qualifiers SHOULD NOT be sent in Observation.component if there's a better place to send them, but recognize that some systems may not always do that. But we do need to indicate that it's not appropriate to use extensions for these sorts of things and provide examples of qualifiers that are appropriate.

view this post on Zulip Lloyd McKenzie (Feb 27 2021 at 16:49):

Certainly "exertion level" or "body position" can't be used outside the context of the observation and they apply "at the same time" as the Observation was made. You're not going to have a separate Observation that says "patient was exercising" and link it to the blood pressure. The assertion of exertion level is an intrinsic part of the blood pressure observation and must be captured at the time the blood pressure is captured.

view this post on Zulip Rob Hausam (Feb 27 2021 at 17:20):

It may be that the only reasonable choice to meet all of the needs is to broaden the intended uses of Observation.component to fully embrace the idea of "qualifying observations" as have been described. If we do that, then obviously the language for Observation.component needs to be changed to reflect that (and given considerable thought and care in doing that).

view this post on Zulip Eric Haas (Feb 28 2021 at 16:16):

I think what is happening in wild is not reflected in the spec and I think the spec needs to catch up

view this post on Zulip Rob Hausam (Feb 28 2021 at 20:36):

I agree that seems to be the case.

view this post on Zulip Robin Bosman (Mar 05 2021 at 11:08):

Following the different inputs in this thread and referring back to the example given in the first post: is it safe to assume then the best way forward is to consider every line in the glucose tolerance test as a separate Observation instance? This would imply one Observation for the panel with different members and every member would look something like this:
<Observation>
[...]
<code>
<coding>
<system value="http://loinc.org"/>
<code value="53093-1"/>
<display value="Glucose^post XXX challenge"/>
</coding>
</code>
[...]
<valueQuantity>
<value value="5.2"/>
<unit value="mmol/l"/>
<system value="http://unitsofmeasure.org"/>
<code value="mmol/l"/>
</valueQuantity>
<component>
<code>
<coding>
<system value="http://snomed.info/sct"/>
<code value="118578006"/>
<display value="Relative time"/>
</coding>
</code>
<valueQuantity>
<value value="0"/>
<unit value="m"/>
<system value="http://unitsofmeasure.org"/>
<code value="m"/>
</valueQuantity>
</component>
</Observation>

view this post on Zulip Rob Hausam (Mar 05 2021 at 21:23):

@Robin Bosman I think that should basically be the idea. But I don't see anything here that specifies what the challenge is (e.g. 75g glucose). And I'm sure that we can all figure what what the "Relative time" is supposed to be relative to (i.e. the glucose challenge), but that also isn't stated anywhere explicitly. It seems like maybe you should add a little more for both of those items?

view this post on Zulip Robin Bosman (Mar 08 2021 at 10:16):

@Rob Hausam Thank you Rob, indeed you are right- the example was more to show the general approach to this.

view this post on Zulip Jay Lyle (Jul 28 2021 at 18:15):

@Rob Hausam , I think I see things like Lloyd. Qualifiers don't mean anything apart from the observation they qualify. I don't follow your objection about contradicting the "one method" text: the "one method" comment just means you can't have two methods in one Observation because you can't articulate a relationship between them. Are you suggesting that body position has to be an independent Member of the Observation it qualifies? Or that we should create a Qualifier extension?

  • panel components (e.g., chem-7): hasMember
  • instruments with dependent parts (e.g., Apgar): component (because you shouldn't report them independently; their union composes the value)
  • multiple answers (e.g., alcohol types): component (fine, but what goes in the component.code? Repeat obs.code?)
  • commonly paired (e.g., BP): text says "component" but this seems divergent from the main guidance. Feh.
  • some qualifiers (method, site): designated observation property
  • other qualifiers (body position, device type): these seem to be meaningless outside the observation and therefore components. To me.

view this post on Zulip Jay Lyle (Jul 28 2021 at 18:16):

OK, now I see more recent posts and agree.

view this post on Zulip Rob Hausam (Jul 29 2021 at 11:32):

@Jay Lyle @Eric Haas @Lloyd McKenzie It seems that carrying this approach foward, using Observation.component and nesting Observations with 'hasMember' will both be general grouping mechanisms that can be used for related observations (for whatever reasons that may be needed). You can and likely would use 'component' when there is no need for an independent existence of the related observations (e.g., for separate retrieval and updating) and also you don't need to specify additional attributes beyond 'dataAbsentReason', 'interpretation' and 'referenceRange' (i.e. no separate values for 'bodySite', 'method', 'specimen', 'device', 'derivedFrom'). It seems like at least the first four of those exclusions may be somewhat arbitrary and potentially problematic based on how general we seem to be looking to make this, but that can be discussed. And then you can use Observation nesting with 'hasMember' for any other groupings that do require either independent existence and/or specifying any of those additional attributes - or you would also be free to use the 'hasMember' nesting for all groupings, if that's what you chose to do so (unless that choice is constrained by specific profiles - e.g., Vital Signs and its subprofiles). Is this where we are wanting to go with the guidance for Observation grouping and specifically the use of Observation.component?

view this post on Zulip Lloyd McKenzie (Jul 29 2021 at 13:21):

I think a key question is whether the additional Observation is meaningful if independent, not just if it needs to be independent. The latter is fuzzy, the former is not. If I communicate the drug without the sensitivity or the sensitivity without the drug, I haven't made a useful statement. If I communicate a white blood cell count without a hemoglobin, that's still completely useable - at least in some cases.

view this post on Zulip Rob Hausam (Jul 29 2021 at 14:28):

I agree that if the additional Observation doesn't have any expected utility or meaning independently, that certainly would be an argument for representing it as a component - but I don't think that is in any way absolute. I think your antimicrobial susceptibility (sensitivity) example is a little mixed up, because communicating the drug without the sensitivity or the sensitivity without the drug isn't ever the issue - those are both always in the same observation or component (i.e. the drug in 'code' and the susceptibility in 'value'). The actual issue is whether it is meaningul to report the drug susceptibility values independently from the organism identification (but of course still being related to it through 'hasMember'). And there the boundary isn't so clear. For instance, if I'm building an antibiogram I might want to do a query for all instances of susceptibility tests for methicillin with a value of 'resistant' or similarly a mecA gene test with a value of 'positive' or 'present' (those two different tests have essentially the same clinical meaning). That antibiogram query would also presumably always be stratifying the susceptibility results based on the identified organism, but it may actually be easier to construct or more efficient to perform that query if the organism identification and susceptibility results are available as independent observations (or at least it certainly would be no worse in that case). That's just one example, and I think that probably in every case you can make similar (and possibly even better) auguments.

Maybe a somewhat better example of where you may want to use an observation component is the flow rate or FiO2 value for the oxygen being administered to the patient when arterial blood gas measurements are being performed. That usually seems to be recorded as an observation - although it's almost never actually measuring the oxygen being administered, but rather is reporting the setting of the device (e.g., nasal cannula, face mask or ventilator) that is administering the oxygen. But putting that aspect aside, the flow rate or FiO2 observation for recording the device settings is being done at the time and specifically for the purpose of the arterial blood gas measurement itself, and it's unlikely (but still not impossible) that it would have other clinical uses (like trending in a flow chart chart), so it is at least clearly a candidate for being represented as an observation component.

But with either example the boundary still has an aspect of "fuzziness", and basing the decision of whether to use an observation component or an independent observation by determining "whether the additional Observation is meaningful if independent" probably doesn't help nearly as much as it might seem to at first. Making that determination is always still going to be dependent on the particular context of use.

view this post on Zulip Lloyd McKenzie (Jul 29 2021 at 16:50):

The drug is only in the code if there's a pre-coordinated concept for "susceptibility to drug X". I accept that's the norm. However, if you're testing susceptibility to something new, then the best you can do is code = "microbial sensitivity" and drug X needs to be communicated as a component value. In that case, it must be a component, because sending it as a separate observation is useless

view this post on Zulip Lloyd McKenzie (Jul 29 2021 at 16:54):

The rationale for capturing flow rate on the O2 sat is that O2 sat of 93% on no oxygen and 93% on 5 l/min oxygen mean vastly different things - it's simply not safe to have the saturation level without the flow rate. Plus, a 'hasMember' relationship wouldn't be appropriate anyhow.

Similar justification for communicating body position, exertion level, cuff size, etc. for a systolic blood pressure measurement. They clearly establish context for and qualify the meaning of the value observed.

view this post on Zulip Lloyd McKenzie (Jul 29 2021 at 16:54):

(And they're not relevant/meaningful on their own)

view this post on Zulip Rob Hausam (Jul 29 2021 at 20:02):

No, I think not quite. Yes, having a code for "susceptibility to drug X" is typically what we see (and I believe all that I have ever seen in any actual lab report instances). A susceptibility test can potentially be done with any antimicrobial drug that any lab has available, including very new and unapproved and investigational drugs, which might not have an existing pre-coordinated code (in LOINC or SNOMED CT or whatever standard terminology is being used). If you find that you need to record susceptibility data in a case where there isn't (yet) an available standard code, that doesn't necessarily mean that all you can do or the best that you can do is send the data as a code of "microbial sensitivity" and "drug X" as a component value. If you can't request and obtain a new standard code quickly enough (which likely would be the best choice), with extensible (or lesser strength) bindings you can instead create and use your own local code for "susceptibility to 'my investigation drug'" or you could even just record it as the drug name in CodeableConcept.text. I don't think that is any worse than what you described using a general code for "microbial sensitivity" and the drug as a component, and using the local code or CodeableConcept.text would almost certainly be better since it follows the same general pattern used for all of the other "standard" susceptibility tests.

I totally agree on the rationale for why you need to capture the O2 flow rate or FiO2 for O2 Sat (or full ABGs)- that's why I used it as an example. I will agree that our documentation on Observation.hasMember doesn't have explicit language that mentions using it as a "qualifier" (assuming that we even know exactly what that means in all cases). And we only added that language for Observation.component in R4 (nothing was said about "qualifiers" or "qualifying" previously, for either 'component' or 'hasMember'). But the documentation on 'hasMember' in 10.1.4.3.3 is quite general and says it can be "used for any supporting result that can be interpreted and used on its own and has one or more different values for method, observation, performer, device, time, and/or error conditions". The description of the 'hasMember' element itself is just "Related resource that belongs to the Observation group" (and the more detailed definition and comments don't specifically mention "qualifiers", but also don't further narrow the use). The O2 flow rate and FiO2 and other "qualifier" examples that you mentioned and I've seen certainly can fit into that, and as I read it are not explicitly precluded. I think saying that using 'hasMember' in this way "wouldn't be appropriate" is definitely a step too far - unless we change the language to really make that clear. If that's what we want we need to be much more explicit about it than we have been so far.

view this post on Zulip Lloyd McKenzie (Jul 29 2021 at 20:33):

@Rob Hausam - what you're saying is "If you have qualifiers, you must pre or post-coordinate them into Observation.code. That's a nice thought, but if it's not how the source system collects data, then it's not going to fly. We already break out certain qualifying elements (e.g. method, body site) even though those too could theoretically (and in some cases practically) be pre-coordinated into the Observation.code. We don't force that though. And we certainly can't realistically introduce distinct elements for all possible qualifications.

I don't want Observation.hasMember to be use for qualifiers. It shouldn't. Observation.component should be used for qualifiers. Components are inseparable from the Observation. members are content that can stand alone. Qualifiers are things that, by definition, can't stand alone (and often that the Observation can't stand without).

view this post on Zulip Lloyd McKenzie (Jul 29 2021 at 20:34):

hasMember should essentially be used for grouping observations like panels. It's not needed for anything else.

view this post on Zulip Rob Hausam (Jul 29 2021 at 21:05):

@Lloyd McKenzie Actually, I'm not at all wanting to say (and I'm pretty sure that I didn't say) that "If you have qualifiers, you must pre or post-coordinate them into Observation.code" (emphasis on the "must"). But I would say that in some cases (like the antimicrobial susceptibility example) that may be the common pattern that is used, and where that is the pattern you may want to continue to use that pattern, and also there is nothing requiring you to deviate from that pattern in order to represent the data (and it may be best if you don't).

This statement that you made I think is the key point:

I don't want Observation.hasMember to be use for qualifiers. It shouldn't. Observation.component should be used for qualifiers.

We could go there, as I said. But we haven't gone there (yet), as I also said. And if we decide that we really want to go there, then we are going to have to be much more explicit and clear about it - and, very importantly, if we actually do make that change then I think we will have to consider it to be a non-compatible change to a normative resource, with all that entails, because it will potentially cause instances that previously were considered to be conformant to no longer be conformant. So this is what we really need to further discuss and determine.

view this post on Zulip Lloyd McKenzie (Jul 29 2021 at 21:14):

I'm not sure that it is non-compatible. I don't read the current guidance as saying that qualifying information can't be sent in components. We could certainly introduce an optional element on component that makes it more clear whether a component is a qualifier or an additional piece of information. But it makes zero sense to force qualifying information (that would historically have been sent as subsequent OBXs) to now have to be sent as custom extensions with distinct extensions for each type of qualifier. That seems to be what you're arguing for. (hasMember is not and never has been viable for qualifiers.)

view this post on Zulip Rob Hausam (Jul 29 2021 at 22:04):

@Lloyd McKenzie I think you're reading into the documentation (on both 'component and 'hasMember') more than what it actually says. If you look at the documentation on observation grouping and Observation.component prior to R4, I think the most fair reading would be that using Observation.component as a "qualifier" would not be considered as a valid use, according to the criteria stated at that time. In R4 we inserted the brief phrase that did include that usage, but we didn't really fully explain even what a "qualifier" is or how that relates to the other guidance on 'component' or related observations linked through 'hasMember'. I agree that the current guidance doesn't say "that qualifying information can't be sent in components". The incompatibility that I was referring to this time is the other way around - that you want the use of 'hasMember' with "qualifier" observations (however that is determined) to not be allowed. First, to be able to say anything intelligent and consistent about observation "qualifiers", we have to define, as clearly as we reasonably can, what an observation "qualifier" actually is - and isn't. And we haven't done that yet. After we've done that, then we can decide and actually document how we want that to apply with 'hasMember'. But we can't (or shouldn't) re-interpret the current documentation and read into it something that it doesn't actually say (and seems to not have been in mind when it was originally written).

view this post on Zulip Lloyd McKenzie (Jul 29 2021 at 22:12):

I think we'd be hard-pressed to find anyone who's sending qualifiers using hasMember - it'd be a very weird (and non-useful) thing to do because it wouldn't allow you to search appropriately. Sticking body position or cuff size in a completely separate observation from the blood pressure just doesn't make sense. If OO feels we can't do a "hard no" on that, then a SHOULD NOT with guidance to use .component instead would suffice.

view this post on Zulip Rob Hausam (Jul 29 2021 at 22:50):

I don't know what OO as a group thinks yet. And I think that you very well may be right that you won't find instances where "qualifier" observations are being sent using 'hasMember'. But how do you and how do we in OO actually know if that's the case? What do you think is the definition (hopefully a reproducibly usable one) of a "qualifier" observation - what it is and isn't? The sum total of everything that we say about this currently in regard to Observation.component and its use as a "qualifier" is (italics mine):

Component observations may make up the separate and individual parts of the observation or may provide qualifying information to Observation.code and may only be able to be understood in relation to the Observation.code (for example, see the $stats operation).

And as I said before, there is no mention of it one way or the other for 'hasMember'. This isn't sufficient to support everything that we've been discussing or wishing for here.

view this post on Zulip Rob Hausam (Jul 29 2021 at 23:04):

There could be two practical steps to take here. We could (1) come up with a definition of a "qualifying" component observation that we could understand and agree on, and (2) we could include guidance to recommend that when "qualifying" observations are being used they should be represented in Observation.component and that it is recommended that they should not be represented as separate Observation resource instances linked by 'hasMember'. And that would be a non-substantive change to the Observation resource.

view this post on Zulip Lloyd McKenzie (Jul 29 2021 at 23:08):

My attempt at #1:

  • an element that further specifies the nature of what was observed and recorded in Observation.value;
  • that could reasonably, in at least some code systems, have been pre-coordinated into the Observation.code;
  • that is important to the appropriate interpretation of the Observation.code;
  • would have no utility/relevance if examined independently of the Observation it qualifies; and
  • does not have an existing core element on Observation that covers the semantics expressed;

I agree to #2. I also think that having an element on component that differentiates whether the component is a qualifier or a property - at least some systems will want to render them (and possibly capture them) differently and an optional element would support that.

view this post on Zulip Lloyd McKenzie (Jul 29 2021 at 23:09):

(And in no way suggesting that this isn't something that OO needs to discuss and decide on. I was just trying to progress the discussion here as much as we could first.)

view this post on Zulip Rob Hausam (Jul 29 2021 at 23:19):

I appreciate this contribution for the definition, and we can discuss that. It defintiely took some back and forth, but I think we've definitely made progress. We probably need to get this on a future OO Main or OO on FHIR agenda. @Hans Buitendijk And we need a tracker (I can create one tonight if you want).

view this post on Zulip Mark Kramer (Sep 19 2021 at 02:09):

Observation needs an element Observation.circumstance to capture context, separate from Observation.component.

view this post on Zulip Grahame Grieve (Sep 19 2021 at 04:14):

is there any other model for Observation that has something like that?


Last updated: Apr 12 2022 at 19:14 UTC