FHIR Chat · Slicing on slices? · shorthand

Stream: shorthand

Topic: Slicing on slices?


view this post on Zulip Jean Duteau (Jan 27 2021 at 22:37):

I have a Bundle that I want to slice with the following requirements:
a) 1 entry with an Organization resource that matches a Registrant profile
b) 0..* entries with an OrganizationAffiliation resource
c) 0..* entries with an Organization resource that matches an Establishment profile
d) 0..1 entry with a DocumentReference resource
e) 0..* entries with no resource (used to delete resources)

I'm struggling in how to slice the Bundle.entry to achieve this and I think that I might have a solution but SUSHI's validation routine might be getting in the way.

If I didn't have (a) and (c), I could slice this on entry.resource with type #type. If I didn't have (e), then I could slice on entry.resource with type #profile. So I thought I would do an initial slice in entry.resource with type #type where (a) and (c) require an Organization resource. Then I would further slice the Organization slice on #profile and specify the specific profile required.

* entry ^slicing.discriminator.type = #type
* entry ^slicing.discriminator.path = "resource"
* entry ^slicing.rules = #open
* entry contains Organizations 1..* MS and EstablishmentAffiliation 0..* MS and EstablishmentDelete 0..* MS and SourceSPL 0..1 MS

* entry[Organizations].resource only Organization
* entry[Organizations] ^slicing.discriminator.type = #profile
* entry[Organizations] ^slicing.discriminator.path = "this()"
* entry[Organizations] ^slicing.rules = #open
* entry[Organizations] contains Registrant 1..1 MS and Establishment 0..* MS

Hopefully this makes sense and is the right way to express what I want. Assuming that is, then this is what I have in my instance:

* entry[Organizations][Registrant].resource = DenmarServicesRegistrant
* entry[Organizations][Registrant].request.method = #POST
* entry[Organizations][Registrant].request.url = "Organization"
* entry[EstablishmentAffiliation].resource = EditorialExpertsEstablishmentAffiliation
* entry[EstablishmentAffiliation].request.method = #POST
* entry[EstablishmentAffiliation].request.url = "OrganizationAffiliation"
* entry[Organizations][Establishment].resource = EditorialExpertsEstablishment
* entry[Organizations][Establishment].request.method = #POST
* entry[Organizations][Establishment].request.url = "Organization"

Unfortunately, with the above, I get the following error from SUSHI:

error Element Bundle.entry:Organizations has minimum cardinality 1 but occurs 0 time(s).
  Line: 193 - 205

Am I not specifying this properly in my instance? If I change the cardinality on the Organization slice from 1..* to 0..*, then SUSHI doesn't complain, but that doesn't seem to express what I want.

view this post on Zulip ryan moehrke (Jan 27 2021 at 23:07):

Firstly, are you getting that from SUSHI? or the IG Publisher? I'm not sure how they get called exactly as I use FSHOnly for all of my tanks,
But I tried to do something very similar myself today as well but I had a different workaround (specific to my usecase) that allowed me to not use the 2nd tier of slicing once I exhausted my ideas and gave up.
From my trial-and-error and what bits of the spec I could parse, I honestly don't think that that form of re-slicing is expected/allowed for at all..

view this post on Zulip Jean Duteau (Jan 27 2021 at 23:08):

that error was from SUSHI. shoot, if it isn't expected/allowed. I'm not sure how I'm going to produce a profile that will validate what I want it to validate

view this post on Zulip ryan moehrke (Jan 27 2021 at 23:13):

what do you need from the delete slice? because you may be able to write an invariant with a bundle.entry.resource.exists().not() implies . . .
if it could be unilaterally applied

view this post on Zulip Jean Duteau (Jan 27 2021 at 23:14):

i just want to say that some of the expected slices would be an entry that tells me to delete a specific resource

view this post on Zulip Jean Duteau (Jan 27 2021 at 23:17):

you do point me in a direction - if I ignore that slice statement, that doesn't preclude instances to include those since the slicing is open, but for the slices that are recognized, it will do the proper validation.

view this post on Zulip Chris Moesel (Jan 28 2021 at 12:57):

Hey @Jean Duteau. Have you tried using two discriminators? Recall that ^slicing.discriminator is an array -- so I think you can discriminate by #type and #profile at the same time -- and slices just need to ensure unique combinations of the resource and profile. I think. So... something like:

* entry ^slicing.discriminator[+].type = #type
* entry ^slicing.discriminator[=].path = "resource"
* entry ^slicing.discriminator[+].type = #profile
* entry ^slicing.discriminator[=].path = "resource"

view this post on Zulip Chris Moesel (Jan 28 2021 at 13:05):

I also think what you're trying to do with re-slicing makes sense (although I noticed that your re-slicing discriminator path is wrong). That said, when I read the FHIR spec on re-slicing, it only speaks in terms of re-slicing a slice defined in a parent profile. I don't know if that's just lack of imagination on the part of the spec author, or if it's an actual requirement of re-slicing.

That aside, SUSHI should allow the basic mechanism you're trying to do, and clearly there is an item in entry[Organizations] -- so this seems like perhaps SUSHI's card counting logic is getting messed up by the re-slicing. We can look into it.

view this post on Zulip Chris Moesel (Jan 28 2021 at 13:28):

OK, I've filed SUSHI#742 for this and also implemented a simple example of it at FSHOnline/#/share/3opCADp.

view this post on Zulip ryan moehrke (Jan 28 2021 at 15:11):

huh, looks like the double-slice is resolved through sushi as

"id":"Bundle.entry:observations/heartrate"
"path":"Bundle.entry"

which if double-slicing is even possible I feel like is the wrong way to express it.. But I still read the re-slicing info in the spec as adding to the current discriminators and slice definitions rather than doing something (useful) like this: another form of slicing in only one iteration of a slice at the same level.

view this post on Zulip Jean Duteau (Jan 28 2021 at 17:37):

Chris Moesel said:

Hey Jean Duteau. Have you tried using two discriminators? Recall that ^slicing.discriminator is an array -- so I think you can discriminate by #type and #profile at the same time -- and slices just need to ensure unique combinations of the resource and profile. I think. So... something like:

Yes, I tried that, but the problem is that for the #profile discriminator to work, it appears that you have to have something in resource and I don't for the DELETE transactions. That's why I thought to slice on #type which doesn't appear to require that and then slice within that one slice.

view this post on Zulip Jean Duteau (Jan 28 2021 at 17:40):

ryan moehrke said:

huh, looks like the double-slice is resolved through sushi as

"id":"Bundle.entry:observations/heartrate"
"path":"Bundle.entry"

which if double-slicing is even possible I feel like is the wrong way to express it.. But I still read the re-slicing info in the spec as adding to the current discriminators and slice definitions rather than doing something (useful) like this: another form of slicing in only one iteration of a slice at the same level.

I agree with Ryan about the slicing paths to not seem correct and that is potentially why you are getting the error that Bundle.entry has minimum cardinality of 2. I was able to get this to go through validation by setting the mins all to 0. But then the validator complained, so I'm pretty sure that this isn't an intended means of re-slicing.

view this post on Zulip ryan moehrke (Jan 28 2021 at 17:57):

if there is a way to explicitly say missing is expected in a slice (per discriminator) and another way to explicitly say that missing is inconsequential to slice matching, I can see how multiple discriminators could work. But again, I did not see a way to do that. And without that clarification of missing-expected and missing-agnostic I see no way how tooling can actually resolve slices against multiple discriminators unless every slice has some value/binding/etc. for each discriminator path given.

view this post on Zulip Jean Duteau (Jan 28 2021 at 17:58):

exactly! although I will say that slicing on #type seems to allow for a missing as I use that in a different profile and it works. But it doesn't seem to be allowed on #profile because the validator needs an actual instance of something to determine what it's profile is.

view this post on Zulip Jean Duteau (Jan 28 2021 at 17:59):

in fact, I just checked and I use multiple discriminators in another profile where missing is allowed. It seems that missing is allowed for anything that the validator doesn't have to resolve into something, i.e. if your path is x.resolve() or if the type is #profile.

view this post on Zulip ryan moehrke (Jan 28 2021 at 18:00):

I think all the tooling available won't let you not have a type (it just inherits all of the possible options from the parent StructureDef) so that may be why type works without an explicit typing in the slice
but how does it treat a missing value? as nothing is expected and if something exists then it's not the slice in question? or that the missing value does not matter for matching that particular slice and only the other discriminator(s) matter and are sufficient for mutually exclusive slice matching?

view this post on Zulip Chris Moesel (Jan 28 2021 at 18:03):

ryan moehrke said:

huh, looks like the double-slice is resolved through sushi as

"id":"Bundle.entry:observations/heartrate"
"path":"Bundle.entry"

which if double-slicing is even possible I feel like is the wrong way to express it.

Using / to separate the layers of slices in re-slicing (splitting a slice into sub-slices) is straight from the spec:
image.png

view this post on Zulip Jean Duteau (Jan 28 2021 at 18:08):

I have a slice on Questionnaire.item where my discriminator is #value on type and #value on an extension(blah). In my various slice definitions, I only specify the extension's value if I have multiple slices with the same item.type. I believe that the validator therefore matches any value of the extension, including no extension specified at all, as meeting the slice condition. And since I don't have multiple slices with the same item.type that doesn't then specify a specific item.extension(blah).value my slicing covers the space I intended.

view this post on Zulip Jean Duteau (Jan 28 2021 at 18:11):

ryan moehrke said:

but how does it treat a missing value? as nothing is expected and if something exists then it's not the slice in question? or that the missing value does not matter for matching that particular slice and only the other discriminator(s) matter and are sufficient for mutually exclusive slice matching?

I wonder if there is a precedence to validating multiple discriminators? In the slice I just talked about, item.type is listed first so it segments the slicing space first? And since I only have one slice with item.type = #string, it doesn't matter what the value of the extension is, even if the slice definition is silent?

view this post on Zulip ryan moehrke (Jan 28 2021 at 18:19):

Chris Moesel said:

Using / to separate the layers of slices in re-slicing (splitting a slice into sub-slices) is straight from the spec:
image.png

interesting... that implies that this functionality that we want is explicitly allowed (and has been designed for at least in the spec) now the question turns to why isn't it working like we want it to

view this post on Zulip Chris Moesel (Jan 28 2021 at 18:22):

I think it's just a SUSHI bug in counting occurrences of base slices when they've been re-sliced. The real question is if the IG publisher accepts it or not. If the IG publisher accepts it then I think the only issue is the SUSHI cardinality counting bug -- which someone will be looking at during our current 2-week sprint.

view this post on Zulip ryan moehrke (Jan 28 2021 at 18:23):

Jean, if you don't mind can I see that profile you mentioned? that slices based on type and then extension if needed?
I just want to see how it manifests in the actual structure def in case I'm missing something

view this post on Zulip Jean Duteau (Jan 28 2021 at 18:24):

Questionnaire.fsh

view this post on Zulip Chris Moesel (Jan 28 2021 at 18:24):

If the IG Publisher does not accept it, then maybe I am interpreting the spec wrong. There is also the matter that the spec seems to imply this would mainly happen in regard to reslicing a slice from a parent profile -- not reslicing a slice from the current profile. Although I don't see what the real difference would be.

view this post on Zulip ryan moehrke (Jan 28 2021 at 18:57):

putzing around with your questionnaire fsh jean, it looks like the cause of your error might not be the slicing per se, but the use of slice names as indexes in the instance, I haven't been able to exhaustively test but once I switched to slice names in the instance you gave I saw a similar error from sushi
maybe switching to regular integer (or soft) indexes will get you past that particular hump for now and then we can see if the ig publisher / validator likes it.

view this post on Zulip Jean Duteau (Jan 28 2021 at 18:59):

right. we can do that with the latest version of SUSHI because the team relaxed that validation. I would try that but I moved on for my current batch of profiles.

view this post on Zulip Chris Moesel (Jan 28 2021 at 18:59):

I haven't had a chance to look at the FSH, but using slice names in the instance does have some advantages -- namely that it will automically apply any required fixed values for you. But if you don't need that, you could try switching to soft indexing. That basically entirely turns off SUSHI's slice validation.

view this post on Zulip ryan moehrke (Jan 28 2021 at 19:00):

well that would make sense as to why we don't see slicing validation errors when we don't use them huh :p

view this post on Zulip Chris Moesel (Jan 28 2021 at 19:28):

FWIW, I switched the Questionnaire instance to specify items by slicename instead of index and it worked just fine for me. I'm using SUSHI 1.1.0. I didn't run the publisher, so it may still fail there -- but SUSHI liked it just fine, and it even allowed me to remove some of the type and extension assignments in the instance (since calling out the slice by name automatically applied them).
Questionnaire.fsh


Last updated: Apr 12 2022 at 19:14 UTC