Skip to content

Instantly share code, notes, and snippets.

@jmandel
Last active August 29, 2015 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jmandel/feb111c54645a5ff7e4d to your computer and use it in GitHub Desktop.
Save jmandel/feb111c54645a5ff7e4d to your computer and use it in GitHub Desktop.
# Questions about Profiles (from Lipid Report example)

The following snippet tries to say "the report's name must be LOINC:57698-3.

    <element>
      <!-- I wonder whether this means *all* codings under "name" must now conform to the constraints below, or just *any* ? -->
      <!-- If we'd allow non-primitive valueXXX, we'd need only one fixed value at DiagnosticReport.name, but then, how do we define equality for complex types? -->
      <path value="DiagnosticReport.name.coding.system"/>
      <definition>
        <min value="1"/>
        <max value="1"/>
        <valueUri value="http://loinc.org/"/>
      </definition>
    </element>
    <element>
      <path value="DiagnosticReport.name.coding.version"/>
      <definition>
        <min value="0"/>
        <max value="0"/>
      </definition>
    </element>
    <element>
      <path value="DiagnosticReport.name.coding.code"/>
      <definition>
        <min value="1"/>
        <max value="1"/>
        <valueCode value="57698-3"/>
      </definition>
    </element>

But does it also match (for example):

name: {
  coding: [{
    system: "http://loinc.org"
  },{
    code: "57698-3"
  }]
}

If not... why not? Is this logic captured somewhere explicitly?

The following snippet declares a slicing group for a report's results, by name:

    <element>
      <path value="DiagnosticReport.result"/>
      <slicing>
        <discriminator value="name"/>
        <ordered value="true"/>
        <rules value="closed"/>
      </slicing>
      <definition>
        <comments value="Cardinality 3..4, since chol, trig, hdlc are mandatory, ldlc is optional"/>
        <min value="3"/>
        <max value="4"/>
      </definition>
    </element>

But shouldn't it read:

<path value="DiagnosticReport.result.reference"/>

? Otherwise, how can a profile refer to content or extensions attached directly to the ResourceReference itself (vs. the target of the reference)?

When a report's results on Observation.name, how does matching occur? For example, for each of the following pairs, would the two Observation.names belong to the same slice or difference slices?

Add an optional property:

name: {
  coding: [{
    system: "a",
    code: "b"
  }]
}

__vs__

name: {
  coding: [{
    system: "a",
    code: "b",
    version: "c"
  }]
}

Add an extra (empty) coding:

name: {
  coding: [{
    system: "a",
    code: "b"
  }]
}

__vs__

name: {
  coding: [{
    system: "a",
    code: "b"
  }, {}]
}

Change of order

name: {
  coding: [{
    system: "c",
    code: "d"
  }, {
    system: "a",
    code: "b"
  }]
}

__vs__

name: {
  coding: [{
    system: "a",
    code: "b"
  }, {
    system: "c",
    code: "d"
  }]
}

That's just a few examples -- the point being: what are the semantics here?

Same question applies to repeating elements...

Our current spec says:

the profile SHALL nominate a "discriminator" - a contained element that is used to discriminate among the different slices. The profile SHALL fix the value of the contained element for each slice, or if the contained element has a terminology binding, it SHALL be associated with a complete binding with a version specific Value Set ...

Can the discriminator be a deep path into a complex datatype, like "reference.name.coding"?

Also, "SHALL fix the value of the contained element" doesn't appear to apply in the fix-by-reference-to-a-profile technique used in the lipid panels example. Is this another special case? (e.g. it would be "fix directly", "point to a value set", or "point to a profile"?)

We see examples of "constraints" applied to a resource:

      <path value="Observation"/>
      <definition>
        <short value="Triglyceride measurement"/>
        <formal value="Triglyceride measurement"/>
        <constraint>
          <key value="value-or-comment"/>
          <name value="Must have valueQuantity or comment"/>
          <severity value="error"/>
          <human value="If a value result is not available, use the comments field"/>
          <!-- notice how the xpath actually refers to valueQuantity, not value[x] -->
          <xpath value="exists(f:valueQuantity) or exists(f:comment)"/>
        </constraint>

and then a "condition" that appears to refer to this constraint:

   <element>
      <path value="Observation.value[x]"/>
      <definition>
        <short value="Actual result"/>
        <formal value="The actual value of the triglyceride measurement"/>
        <comments value="If not available, a comment should be given"/>
        
        <!-- Was already 0..1 in base, but it's good to restate it, value-or-comment controls the actual optionality -->
        <min value="0"/>
        <max value="1"/>
        <type>
          <code value="Quantity"/>
          <profile value="#lipidQuantity"/>
        </type>
        <condition value="value-or-comment"/>
        <mustSupport value="true"/>
      </definition>

But :

1. the way a condition refers to a constraint is never described.

All we get is:

The condition element is used to assert that a constraint defined on another element affects the allowed cardinality of this element.

and

Profile.structure.element.definition.condition Definition A reference to an invariant that may make additional statements about the cardinality or value in the instance. Control 0..* Type id

2. What are the semantics of "condition"?

In the Observations profiled above, the constraint would seem to say everything that's needed. Why are two paths (value[x] and comment) referring to it explicitly? Is this just so the human-readable docs can be rendered with warning icons in the right spots, or are there hard, computable semantics attached to the appearance of condition at a sub-path?

In the examples diagnostic report, we have only four structures. Missing are:

  • ldlCholesterol
  • hdlCholesterol
  • lipidQuantity
@grahamegrieve
Copy link

1 - "the report's name must be...": yes, you're right. Should limit the coding to 1 as well. Or else fix to a value set containing a single code

2 - yes, I guess I agree. note that this was my decision when I wrote it in the first place, to overlook this complexity

3 - depends on what the profiles say. if the profile says both match, then both match. change of order - that's a property of the slicing whether that is allowed or not.

4 - yes, can be deep (though you can get yourself into trouble like that), and yes, we could adjust the language to say that a profile can fix a value or values by referring to other profiles that do so

5- because the id matches on both. The purpose is documentation, such as in the rendered specification. It's not only rendering but it is only documentative. There is nothing computable associated with it

@jmandel
Copy link
Author

jmandel commented Sep 9, 2014

@grahamegrieve re #3, I don't understand:

if the profile says both match, then both match

How does the profile express this (or not)?


Re #4, OK. Let me know if I should file a tracker item.

Re: #5, if there are no semantics associated with "condition," it would be good to state this explicitly in the spec.

@grahamegrieve
Copy link

well, the profile makes the rules for the possible values for the value of "x" (whatever x is, that it's sliced by). So the algorithm is simple: work through the profiles seen if the value meets the constraints defined by the applicable slice profile. If it does, then it's a match. So if the profile doesn't say anything about coding.version, or other codings, then they have nothing to do with whether it's a match or not

@jmandel
Copy link
Author

jmandel commented Sep 9, 2014

Hmm, but do profiles have the expressivity to convey these distinctions? How would I describe these distinctions in profiles?

@ewoutkramer
Copy link

  • 1 - I agree, will fix
  • 2 - Grahame, what does your validator currently do here? Do we need to change this before Chicago?
  • 3 - I had the same kind of questions, looks like a discussion for the face to face meeting. That's why I put this question in a comment in the differential as well. Also, I wonder about what happens if we allow non-primitives as fixed values and how that will influence matching.
  • 6 - Missing observation structures...
    They seem to be present in https://github.com/ewoutkramer/fhir-net-api/blob/develop/src/Hl7.Fhir.Api.Tests/example-lipid-profile-testmessage.xml, where did you look?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment