FHIR Chat · Narrow Quantity to Duration and Age · conformance

Stream: conformance

Topic: Narrow Quantity to Duration and Age


view this post on Zulip Chris Moesel (May 18 2020 at 20:33):

If I want to say that Observation.value[x] can only be a Duration or an Age, how do I do that? The value[x] choice does not contain Duration or Age specifically, but it does contain Quantity -- and Duration/Age are specializations of Quantity.

In the past, I thought that this worked:

      {
        "id": "Observation.value[x]",
        "path": "Observation.value[x]",
        "type": [ { "code": "Duration" }, { "code": "Age" } ]
      }

but now the Publisher barks at that:

illegal constrained type Duration from Quantity, CodeableConcept, string, boolean, integer, Range, Ratio, SampledData, time, dateTime, Period in http://hl7.org/fhir/StructureDefinition/Observation

Is what I've done above legal or is this something you need to drop into FHIRPath to express?

view this post on Zulip Grahame Grieve (May 18 2020 at 23:08):

it's not legal. Choice types are final, in effect; you'll have to use FHIRPath

view this post on Zulip Lloyd McKenzie (May 19 2020 at 01:29):

You should be able to specify a targetProfile for the type

view this post on Zulip Grahame Grieve (May 19 2020 at 05:26):

You mean profile not targetProfile but Age and Duration are not profiles

view this post on Zulip Chris Moesel (May 19 2020 at 12:53):

Right. At first I thought profile too, but they are specializations, not constraints, so we can't use profile. So... FHIRPath it is.

view this post on Zulip Lloyd McKenzie (May 19 2020 at 15:19):

Why are they specializations - they don't add any new elements...

view this post on Zulip Lloyd McKenzie (May 19 2020 at 15:19):

I'm pretty sure I've referenced them with profile and it's worked...

view this post on Zulip Chris Moesel (May 19 2020 at 15:33):

Why are they specializations

We just had this same exact question/conversation during our team meeting. We couldn't figure out why they are specializations either. Best we could come up w/ is that in cases where they are used as choices in core spec, it allows valueAge and valueDuration to be used instead of valueQuantity -- which is probably a bit more explicit from a user perspective. But still... I'd be interested to hear the story behind it. It looks like they were constraints in DSTU2.

view this post on Zulip Lloyd McKenzie (May 19 2020 at 15:36):

@Grahame Grieve

view this post on Zulip Grahame Grieve (May 19 2020 at 19:10):

they were constraints, but that meant that when you used them, you didn't really use them. People got confused by this - for instance, a value that was a choice of Age and Duration was actually a choice of Quantity. So we changed them to specializations instead of constraints. We discussed that this meant that you couldn't do what Chris wants to do, but we felt that it wouldn't happen very often (and we were right - it was such a long time till someone tried to do it that Lloyd didn't remember the discussion)

view this post on Zulip Chris Moesel (May 19 2020 at 19:54):

And I'll admit that this didn't come up in a real world use case for us either. It came up in a fairly contrived unit test in SUSHI.

view this post on Zulip Chris Moesel (Jun 03 2020 at 18:27):

Followup question. We've established that the following is an illegal constraint because Duration and Age are not in the original type list (even though their parent, Quantity, is in the type list):

{
  "id": "Observation.value[x]",
  "path": "Observation.value[x]",
  "type": [ { "code": "Duration" }, { "code": "Age" } ]
}

It appears that if I try to do a similar thing, but with Bundle.entry.resource instead, the IG Publisher is happy with it. For example, even though Bundle.entry.resource only has Resource in its type list, I can apparently constrain it to sub-types like this:

{
  "id": "Bundle.entry.resource",
  "path": "Bundle.entry.resource",
  "type": [ { "code": "Patient" }, { "code": "Condition" }]
}

view this post on Zulip Chris Moesel (Jun 03 2020 at 18:29):

  1. Is that second example (w/ Bundle.entry.resource) indeed valid?
  2. If so, what makes the first invalid? Is it because it is a choice (e.g., the [x] makes the type list final)? I think this is what Graham implied, but I want to confirm before I code up SUSHI this way.

view this post on Zulip Lloyd McKenzie (Jun 03 2020 at 18:43):

@Grahame Grieve

view this post on Zulip Chris Moesel (Jun 03 2020 at 18:55):

Upon further investigation, the following ALSO does not work:

{
  "id": "DeviceDefinition.quantity",
  "path": "DeviceDefinition.quantity",
  "type": [ { "code": "Duration" }, { "code": "Age" } ]
}

view this post on Zulip Grahame Grieve (Jun 03 2020 at 18:57):

because Observation.value has a set of concrete types, but Bundle.entry.resource has a single abstract type

view this post on Zulip Chris Moesel (Jun 03 2020 at 19:00):

Ooooohhh... is that the key? We can do it on something that is type Resource because Resource is abstract, but we can't do it on something like Quantity because it is concrete? Because it can't just be due to the choice since DeviceDefinition.quantity also does not work.

view this post on Zulip Grahame Grieve (Jun 03 2020 at 19:01):

Unless the type is abstract, the type is final

view this post on Zulip Chris Moesel (Jun 03 2020 at 19:02):

And by final, you mean it cannot be replaced by specializations in the type list. If you want to constrain it to a specialization you have to fall back to FHIRPath invariants.

view this post on Zulip Chris Moesel (Jun 03 2020 at 19:03):

I think I understand now. Thank you, @Grahame Grieve!

view this post on Zulip Nick Freiter (Jun 12 2020 at 16:05):

@Grahame Grieve , we were under the impression that if we wanted to use FHIRPath to express on a profile that a Quantity element should be a Duration, we would place the following in the constraint array on the Quantity type element in question:

 {
            "key": "dur-1",
            "severity": "error",
            "human": "Type is a duration",
            "expression": "is(FHIR.Duration)",
}

However, this leads to an error in validation of any instance of that profile, and the error seems to be caused by the fact that the element is of type Quantity, but the FHIRPath constraint indicates it should be of type Duration. We thought this would be allowed since Duration is a child type of Quantity. We have also tried using the conformsTo operator instead of is, and that also leads to validation errors. Was the above not what you meant when you said we would have to use FHIRPath to constrain a Quantity to a Duration?

view this post on Zulip Grahame Grieve (Jun 12 2020 at 19:35):

it wasn't what I meant.

"expression": "is(FHIR.Duration)"

No, because that's just saying again that the type is a Duration, but it can't be since the binding is final.

view this post on Zulip Grahame Grieve (Jun 12 2020 at 19:35):

conformsTo - maybe that should work if you provide a canonical URL? but that would really be a bug on my part since it can't conform to the definition, since the definition says it's a type

view this post on Zulip Grahame Grieve (Jun 12 2020 at 19:38):

 {
            "key": "dur-1",
            "severity": "error",
            "human": "Type is a duration",
            "expression": "$this.memberOf('http://hl7.org/fhir/ValueSet/all-time-units)",
}

view this post on Zulip Chris Moesel (Jun 12 2020 at 21:45):

So are you saying there is no uniform way for a profile author to succinctly say that an element of TypeA should be a specific specialization of that type? Is that intentional because a specialization can introduce new elements -- and it's really only rather unfortunate here because these specific specializations (Duration and Age) don't introduce new units (e.g., they act much more like constraints)?

view this post on Zulip Grahame Grieve (Jun 12 2020 at 21:49):

if a specialization is allowed then you can say that it must be done - exactly how you did it. But since it's not allowed, you can't satisfy that constraint

view this post on Zulip Chris Moesel (Jun 12 2020 at 21:54):

OK. I think we just got confused because Duration and Age act more like constraints, so it feels like they should be allowed, even if they're not. We'll update SUSHI to yell when an author tries to constrain a type to a specialization (if that specialization hasn't already been explicitly allowed via a choice).

view this post on Zulip Grahame Grieve (Jun 12 2020 at 21:56):

it's unfortunate, I agree, because they do feel a lot like constraints. they used to be. But people were confused by that since they couldn't listed as types in resource definitions/profiles, and didn't appear in choices.


Last updated: Apr 12 2022 at 19:14 UTC