FHIR Chat · Slicing by target profile of a reference? · conformance

Stream: conformance

Topic: Slicing by target profile of a reference?


view this post on Zulip Simone Heckmann (Aug 09 2017 at 11:16):

Is it possible to slice by target profile of a reference, and if so: what's the discriminator?

view this post on Zulip Simone Heckmann (Aug 09 2017 at 11:17):

I would have guesses "Type:Profile Path:reference" but that doesn't seem to work

view this post on Zulip Michel Rutten (Aug 09 2017 at 13:22):

Great question...!

The spec may provide some clues:
https://www.hl7.org/fhir/profiling.html#discriminator

I think discriminator type "profile" is specifically intended to match type.profile and not type.targetProfile. Maybe you could leverage the special .resolve() fhir path expression that is specifically allowed in this context?

view this post on Zulip Michel Rutten (Aug 09 2017 at 13:32):

Looks like the LipidProfile example tries to slice DiagnosticReport.result on target profile:
http://hl7.org/fhir/lipidprofile.profile.xml.html

<discriminator>
  <type value="value"/>
  <path value="reference.code"/>
</discriminator>

However I'm not sure if this is actually correct, as the documentation on discriminators suggests the use of the resolve() operator...?

view this post on Zulip Michel Rutten (Aug 09 2017 at 13:35):

The official documentation suggests the following syntax:

Context: List.entry
Discriminator type: profile
Discriminator path: item.reference.resolve()

"Entries are differentiated by a profile tag on the target of the reference, as specified by a structure definition"

view this post on Zulip Michel Rutten (Aug 09 2017 at 13:36):

@Grahame Grieve & @Lloyd McKenzie any suggestions?

view this post on Zulip Lloyd McKenzie (Aug 09 2017 at 20:32):

I'll defer to @Grahame Grieve on this one.

view this post on Zulip Grahame Grieve (Aug 10 2017 at 04:51):

well, the lipid thing looks wrong, though the validator works on it. weird.

view this post on Zulip Grahame Grieve (Aug 10 2017 at 04:52):

the official documentation Michel quoted is what I think is correct

view this post on Zulip Rob Hausam (Nov 30 2018 at 09:45):

@Grahame Grieve @Lloyd McKenzie @Michel Rutten I'm re-engaging this topic as we have the same question now for the IPS IG and haven't yet found a working FHIRPath expression for the discriminator path. The documentation on this has changed for R4, as 'reference' has been removed and for the List.entry example the discriminator path is now item.resolve(). We're slicing on the Composition.section.entry reference of an already sliced section (for example Composition.section:sectionMedications.entry). Composition.section.entry is modeled differently from List.entry which is used in the documentation, as Composition.section:sectionMedications.entry itself is of type Reference rather than the additional List.entry.item element. An example of what we have right now (we've tried various permutations) is:

        <element id="Composition.section:sectionMedications.entry">
            <path value="Composition.section.entry"/>
            <slicing>
                <discriminator>
                    <type value="profile"/>
                    <path value="resolve()"/>
                </discriminator>
                <rules value="openAtEnd"/>
            </slicing>
            <min value="1"/>
            <mustSupport value="true"/>
        </element>
        <element id="Composition.section:sectionMedications.entry:medicationStatement">
            <path value="Composition.section.entry"/>
            <sliceName value="medicationStatement"/>
            <min value="1"/>
            <type>
                <code value="Reference"/>
                <targetProfile value="http://hl7.org/fhir/uv/ips/StructureDefinition/MedicationStatement-uv-ips"/>
            </type>
            <mustSupport value="true"/>
        </element>
        <element id="Composition.section:sectionMedications.entry:medicationStatement.reference">
            <path value="Composition.section.entry.reference"/>
            <min value="1"/>
            <mustSupport value="true"/>
        </element>

And when parsing an IPS bundle example the QA shows this error:

Bundle/IPS-examples-Bundle-01: Bundle.entry[5].resource.code.coding error   Unable to resolve discriminator

Most likely we're doing something wrong, so any suggestions as to what the correct FHIRPath syntax should be for this would be most welcome.

view this post on Zulip Rob Hausam (Nov 30 2018 at 09:52):

I've looked into where the 'Unable to resolve discriminator' exception is thrown in FHIRPathEngine, but so far that hasn't really shed any light on the issue.

view this post on Zulip Michel Rutten (Nov 30 2018 at 09:55):

Hi @Rob Hausam, hard to say... the snapshot generator and validator in the FHIR .NET API haven't been updated to R4 yet, so we can't actually test your example. However @Ewout Kramer recently mentioned that he had implemented support for profile-based discriminators. Ewout, can you provide some clarification?

view this post on Zulip Rob Hausam (Nov 30 2018 at 14:57):

I think this issue was different than we originally thought and the error messages are now resolved. But if anyone is able to confirm that the syntax we are using is correct (or not), that would be great.

view this post on Zulip Rob Hausam (Dec 02 2018 at 15:15):

I believe that the resolve() syntax for the path expression is correct, as that fixes the 'Unable to resolve discriminator' error. But, unfortunately, it results in a new type of error when evaluating the example bundle:

Problem evaluating slicing expression for element in profile http://hl7.org/fhir/uv/ips/StructureDefinition/Composition-uv-ips path Bundle.entry[1].resource.section[1].entry (fhirPath = true and resolve().conformsTo('http://hl7.org/fhir/uv/ips/StructureDefinition/Condition-uv-ips')): null

The reference to the Condition-uv-ips profle is the correct one, but it doesn't recognize the identified resource in the bundle as being one of those, even though the resource instance in the bundle has the meta profile tag:

                <meta>
                    <profile value="http://hl7.org/fhir/uv/ips/StructureDefinition/Condition-uv-ips"/>
                </meta>

Not sure at this point where to look next to fix this, so any suggestions are very welcome.

view this post on Zulip Rob Hausam (Dec 02 2018 at 15:16):

@Grahame Grieve @Lloyd McKenzie @Ewout Kramer @Michel Rutten?

view this post on Zulip Ewout Kramer (Dec 03 2018 at 10:41):

Hi @Rob Hausam, hard to say... the snapshot generator and validator in the FHIR .NET API haven't been updated to R4 yet, so we can't actually test your example. However @Ewout Kramer recently mentioned that he had implemented support for profile-based discriminators. Ewout, can you provide some clarification?

Since I have not implemented this at all yet, these errors must come from the Java IG/validator ;-)

Syntax-wise, the single "resolve()" looks ok, since that is in line with the List.entry example here (http://build.fhir.org/profiling.html#discriminator).

view this post on Zulip Richard Ettema (Dec 03 2018 at 13:56):

@Rob Hausam

Bundle/IPS-examples-Bundle-01: Bundle.entry[5].resource.code.coding error   Unable to resolve discriminator

This error from the ValidationEngine is pointing to the 5th Bundle entry of the IPS-examples-Bundle-01 example resource which is a Condition. The specific path points to the Condition.code.coding element. The "Unable to resolve discriminator" message is being thrown because the IPS Condition Profile's slicing definition on the Condition.code.coding element does not contain a discriminator.path.

Here's the differential definition of the IPS Condition Profile Condition.code.coding element:

    <element id="Condition.code.coding">
        <path value="Condition.code.coding"/>
        <slicing>
            <description value="Discriminated by value set biding"/>
            <rules value="open"/>
        </slicing>
        <definition value="Identification of the condition, problem or diagnosis or recording of &quot;problem absent&quot; or of &quot;problems unknown&quot;."/>
        <min value="1"/>
        <mustSupport value="true"/>
    </element>

As you can see, the slicing element does not contain a discriminator. So, the FHIRPathEngine does not have a path to evaluate.

view this post on Zulip Rob Hausam (Dec 04 2018 at 03:12):

@Richard Ettema Yes, that's what I was referring to (but not explicitly) when I said "I think this issue was different than we originally thought and the error messages are now resolved". We had the "Unable to resolve discriminator" error when the discriminator path was there, and removing the discriminator path (and therefore the entire discriminator including the type since path is required) is what we did to resolve the errors. And I think that makes sense, as the discriminator isn't always required and in this case as long as the value sets that are bound for each slice are not overlapping (as is supposed to be the case) then when they are evaluated the validator can determine the correct slice.

view this post on Zulip Lloyd McKenzie (Dec 10 2018 at 22:13):

If you remove the discriminator, then you're not slicing anymore (or if you are, you're declaring new slices based on the discriminator of the parent...)

view this post on Zulip Rob Hausam (Dec 10 2018 at 22:35):

@Lloyd McKenzie Not sure about that. It's obviously not recommended, but this statement on the profiling.html page clearly indicates that it is allowed: "A structure definition is not required to designate any discriminator at all for a slice, but those that don't identify discriminators are describing content that is very difficult to process, and so this is discouraged." With that said, though, I think we do need a discriminator - but it needs to be one that actually works when validating instance data. So far I haven't been able to discover what that is exactly. If you are now back and have some availability, I would like to find some time to go over with you the details of the slicing and discriminators and the issues that we are having, and either see what we need to do differently for it to work correctly, see what might need still to be fixed in the spec or tooling, or see what we think Grahame may need to agree to pass as an acceptable error or warning.

view this post on Zulip Lloyd McKenzie (Dec 10 2018 at 22:45):

If you're just declaring slicing with a description, you can, but that means there's no computable behavior happening with validators or anything else that doesn't write custom code based on what you put in slicing.description.

view this post on Zulip Lloyd McKenzie (Dec 10 2018 at 22:48):

The validator doesn't currently support slicing by profile of a target reference. Doing so is quite processing intensive. The general recommendation is to instead slice by something that's distinct for each profile (e.g. a fixed code or something). One thing you can do is have your profiles mandate that they're declared in meta.profile and then slice by value looking at that.

view this post on Zulip Rob Hausam (Dec 10 2018 at 22:51):

Agree. We do want the discriminator. We ended up removing it because that wasn't "wrong" and was the only way that we found to resolve some errors. But I want to put it back and have it work.

view this post on Zulip Richard Townley-O'Neill (Jan 22 2019 at 05:42):

@Rob Hausam any progress?

view this post on Zulip Richard Townley-O'Neill (Jan 22 2019 at 05:51):

We have similar problems. When slicing by profile:resolve() the ig publisher give the error

Problem evaluating slicing expression for element in profile http://ns.electronichealth.net.au/ci/fhir/3.0/StructureDefinition/composition-phs-1 path Composition.section[1].entry (fhirPath = true and resolve().conformsTo('http://ns.electronichealth.net.au/ci/fhir/3.0/StructureDefinition/allergyintolerance-summary-1')): null

If I have an example that tries to meet the profile.
We are using STU3

view this post on Zulip Rob Hausam (Jan 22 2019 at 06:03):

@Richard Townley-O'Neill I didn't get back to this over the holidays or leading up to the WGM and we didn't manage to get to it in our evening session on IGs or another time during the week last week in San Antonio. But we need to get it resolved for IPS (using R4). I think I'll start with @Lloyd McKenzie's suggestion to mandate that the instance declares meta.profile and try to slice by value on that via the reference and see if that proves to be a sufficiently workable approach. Not as powerful, but it seems as if it should work. @Grahame Grieve also will be working on IGs and will need time from him if there are still issues.

view this post on Zulip Richard Townley-O'Neill (Jan 22 2019 at 06:09):

Our profiles are mandating meta.profile:

      <constraint>
        <key value="inv-dh-cmp-01"/>
        <severity value="error"/>
        <human value="One meta.profile shall be http://ns.electronichealth.net.au/ci/fhir/3.0/StructureDefinition/composition-phs-1"/>
        <expression value="meta.profile.where($this=&#39;http://ns.electronichealth.net.au/ci/fhir/3.0/StructureDefinition/composition-phs-1&#39;).exists()"/>
      </constraint>

view this post on Zulip Richard Townley-O'Neill (Jan 22 2019 at 06:11):

Oh!. Just reread Lloyd's suggestion. I'll give that a go.

view this post on Zulip Rob Hausam (Feb 04 2019 at 12:34):

@Lloyd McKenzie @Grahame Grieve @Richard Townley-O'Neill @Michel Rutten Does anyone have example(s) of the correct syntax for doing this with resolve()? I'm trying to slice on the fixed canonical value of meta.profile across the reference. I think I'm getting close, but I haven't figured out the correct syntax that works yet.

view this post on Zulip Rob Hausam (Feb 04 2019 at 12:35):

The documentation seems rather sparse on this.

view this post on Zulip Grahame Grieve (Feb 04 2019 at 12:41):

I'll have a chance to look at this on Wednesday my time

view this post on Zulip Rob Hausam (Feb 04 2019 at 12:42):

great

view this post on Zulip Rob Hausam (Feb 06 2019 at 21:23):

@Grahame Grieve Did you have a chance to take a look at this? I'll keep doing some work on it further in the meantime.

view this post on Zulip Grahame Grieve (Feb 07 2019 at 00:02):

do you want to add a test case for this, and we'll iterate on it

view this post on Zulip Rob Hausam (Feb 07 2019 at 00:13):

ok - will do that

view this post on Zulip Michel Rutten (Feb 11 2019 at 11:03):

I @Rob Hausam, I can't find a concrete example of such an expression. You may be able to get some inspiration from a profile created by colleague @Vadim: https://simplifier.net/temporary-swedish-pa/mymedicationrequest
Specifically, look at the expression for constraint "medication-1" on the root element. This expression uses resolve() to inspect another (sibling) element.

view this post on Zulip Chris Grenz (Mar 12 2019 at 09:43):

I'd expect NOT to use resolve when profiling across a reference and instead to rely on the targetProfile element of type. However, that seems to be at odds with the valueset comments. Here's an example:

{
    "differential": {
        "element": [
            {
        "id":"Encounter.participant",
                "path": "Encounter.participant",
                "slicing": {
                    "discriminator": [{
                        "type": "profile",
                        "path": "individual.reference"
                    }],
                    "rules": "open"
                }
            },
            {
        "id": "Encounter.participant:withParticularID",
                "path": "Encounter.participant",
                "sliceName": "withParticularID"
            },
            {
        "id": "Encounter.participant:withParticularID.individual.reference",
                "path": "Encounter.participant.individual.reference",
                "type": [{
                    "code": "string",
                    "targetProfile": "http://example.com/fhir/StructureDefinition/practitioner-with-particular-id"
                }]
            }
        ]
    }
}

view this post on Zulip Chris Grenz (Mar 12 2019 at 09:46):

http://hl7.org/fhir/STU3/valueset-discriminator-type.html in STU3 is silent on the matter. R4 clarified (badly IMO): http://hl7.org/fhir/valueset-discriminator-type.html that resolve() was to be used. This requires the validator to match a .resolve() path with type.targetProfile (backtracking) and a non resolve() path with type.profile.

view this post on Zulip Chris Grenz (Mar 12 2019 at 09:47):

This leaves the question of when both profile and targetProfile are set (which is legal as far as I can tell...)? Is one to be treated as discriminator and the other as validation?

view this post on Zulip Rob Hausam (Mar 12 2019 at 13:09):

Thanks, @Chris Grenz In IPS we still have these questions, and would like to get this "resolved". :)

view this post on Zulip Grahame Grieve (Mar 14 2019 at 07:27):

I don't know the answer to this

view this post on Zulip Chris Grenz (Mar 26 2019 at 09:22):

WGM topic?

view this post on Zulip Chris Grenz (Mar 26 2019 at 09:24):

@Rob Hausam - maybe open a clarification tracker that can be triaged to WGM in person.

view this post on Zulip Rob Hausam (Mar 29 2019 at 22:10):

@Chris Grenz good suggestion - I'll probably do that on the plane home from Finland on Sunday (or maybe tomorrow, but don't think I will get to it tonight after a good but intense week)

view this post on Zulip Patrick Werner (Aug 12 2019 at 21:13):

do we now know the answer to this? I have a also a related question: if i slice on the resource/target profile. Which counts: meta statement about the profile in the target, or if the entry validates against one of the slices, what happens if it validates against 2 slices?

view this post on Zulip Michel Rutten (Aug 13 2019 at 08:34):

Hi @Patrick Werner, interesting question. Ewout explains that the .NET Validator probably performs a "greedy" match, i.e. map to the first slice entry with a matching targetProfile and ignore any others. An advanced validator implementation could try to match against all specified targetProfiles and report ambiguous matches. However this would be quite cpu-intensive, hence the current "greedy" approach.

view this post on Zulip Lloyd McKenzie (Aug 19 2019 at 01:56):

I think the Java reference implementation currently tries to match everything and hollers if it finds more than one (or none). Profiles certainly shouldn't rely on a greedy match approach (i.e. all target profiles need to be mutually exclusive)


Last updated: Apr 12 2022 at 19:14 UTC