FHIR Chat · Extensions vs properties · terminology

Stream: terminology

Topic: Extensions vs properties


view this post on Zulip Brian Postlethwaite (Feb 21 2019 at 10:27):

Wondering what the rationale was to use the property bag in terminology vs using extensions like in rest of fhir.

view this post on Zulip Lloyd McKenzie (Feb 21 2019 at 15:51):

Properties fall within the 80% for code systems. We also need them to filter valuesets

view this post on Zulip Brian Postlethwaite (Mar 08 2019 at 03:09):

Just a question on this, does the terminology stuff support extensions (technically yes) but do these then flow through the expansions?
Do if I put an extension on a concept in a code system and this is returned in an expansion on a valueset, should the extensions come too?
(the properties don't as there is no place to put them)

view this post on Zulip Peter Jordan (Mar 08 2019 at 03:25):

Extending concepts in a Code System is facilitated by Code System Supplements see http://hl7.org/fhir/codesystem.html at 4.8.8; noting the caveat on their use in ValueSet expansions in the 'trial use' box.

view this post on Zulip Jim Steel (Mar 08 2019 at 04:58):

I don't think supplements help with getting extra information back in an expansion (it can add properties, but they won't/can't come back in an expansion any more than other CodeSystem properties can).

@Michael Lawley was talking about something like a ValueSet/$lookup operation, that might meet some of the needs, in https://chat.fhir.org/#narrow/stream/179202-terminology/topic/ValueSet.2F.24lookup

view this post on Zulip Brian Postlethwaite (Mar 08 2019 at 10:56):

So, in summary, terminology expansion has no standard extensibility mechanism.

view this post on Zulip Robert McClure (Mar 08 2019 at 16:20):

You all are much more knowledgable on the technical issues, but @Peter Jordan is exactly correct that code system supplements is intended to allow you to add properties and additional relationships to a code system, they just can not add additional concepts (that is a code system fragment).

It was our intent to be able to specify that an expansion operation use any number of supplements when generating the expand with the expectation that the result would include anything added in the supplement. @Jim Steel you seem to say something different?

As for code system $lookup (or valueset $lookup) - I certainly assume the same behavior. In fact, the whole point of a supplement (or a fragment) is that they can be added to the code system for any operation. @Rob Hausam am I missing something?

view this post on Zulip Jim Steel (Mar 09 2019 at 01:31):

My point (and my understanding of the original question from @Brian Postlethwaite ) was that the concept elements that come back in a ValueSet from an $expand request cannot currently have properties in them. So regardless of whether the property values are defined in the original CodeSystem or in a supplement, they cannot currently come back in the result of $expand.

view this post on Zulip Brian Postlethwaite (Mar 09 2019 at 01:37):

Correct, and same with extensions on the concepts in the code system. They don't d
Come back either.

view this post on Zulip Peter Jordan (Mar 09 2019 at 02:22):

Depends what you mean by 'extensions' in this context (extensions on one of the coded data types?). Supplements that are additional designations (e.g. an alternative language) can be returned in ValueSet expansions. However, as Jim says, properties cannot - whether they are part of the 'core' Code System or supplementary properties; at present, these are only returned by a CodeSystem $lookup operation.

view this post on Zulip Michael Lawley (Mar 09 2019 at 03:40):

at present, these are only returned by a CodeSystem $lookup operation

And there are a couple of (informal) proposals floating around to either:
1. extend /ValueSet/$expand so that it can return a concept's properties, or
2. introduce /ValueSet/$lookup that acts just like /CodeSystem/$lookup but that takes a valueset as a parameter instead of a code and does a $lookup on all members of the valueset's expansion

From one perspective, option 1 seems like the most straightforward. However, I have also proposed something like /ValueSet/$translate to enable (efficient) batch-translation of multiple concepts. So option 2 is really about having a consistent mechanism for performing terminology operations on a set of codes rather than just a single code.

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

so there's no simple way to pipe operations because you need some language to transform between first output and second input - and it rapidly gets yucky.

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

right now, the only way to do this is

  • $expand to get the list. Note that supplements may alter the list if it's specified extensionally based on properties and the supplements provide values for the properties
  • N $lookups to get the properties

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

this is one of 3 deficiencies in the API that we need to solve. I'd like to pilot a proposal at Montreal on this.

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

the other deficiencies:

  • a single call that takes any kind of resource and populates all the display values
  • dealing with the v2/CDA/openEHR issues (alternative system identifiers)

view this post on Zulip Rob Hausam (Mar 14 2019 at 12:36):

Are you going to make the proposal for the alternative to $expand --> N $lookups? What do you mean by pilot for this?

view this post on Zulip Grahame Grieve (Jun 04 2019 at 05:47):

ping on this. Can we talk about this at DevDays?

view this post on Zulip Rob Hausam (Jun 04 2019 at 11:57):

Sure. Sounds like a good plan.

view this post on Zulip Paul Lynch (Jun 04 2019 at 15:30):

@Grahame Grieve Coincidentally we are just getting back to focusing on this problem. I won't be at DevDays, unfortunately, but I like the proposal you made last year where you wrote:

"an alternative approach which is more value set centric - and probably better for getting properties, is to add to value set (probably extensions for now) a column : string 0..* for each contains, and a column: {name, uri, type} to the expansion that defines the columns. and some kind of column= parameter in the $expand"

Related to this problem for us, and possibly worth looking at together, is the need for the client to select which properties are searched during an $expand.

view this post on Zulip Brian Postlethwaite (Jun 04 2019 at 20:59):

Count me in on that dev days discussion

view this post on Zulip Jim Steel (Jun 04 2019 at 23:44):

I think @Michael Lawley and I would also like to be in that discussion

view this post on Zulip Grahame Grieve (Jun 10 2019 at 18:18):

pop up at DevDays: Wednesday 11.55 - 12.35: McKinley: Returning extensions in value set expansions

view this post on Zulip Jim Steel (Jun 12 2019 at 19:05):

@Grahame Grieve You should come, its awesome ;)

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

Outcomes:

1. define an ordinal property (can be pre-adopted in <R5)
1a. change the ordinal value extension to only be used in Questionnaire (GF#22698)
2. define a way to put properties in expansions in R5 (match the CodeSystem pattern)
3. define an extension to put properties in expansions in R4 (matching the CodeSystem pattern)
4. define a way for a client to ask for particular properties in expansions : property string 0..* a code or a URI for a property that the client wishes to be returned (or *)
5. define a way for a value set to specify the default returned properties
6. document the use of :in to search by property value
7. define a way for a value set to specify the order if filtered based on properties

view this post on Zulip Grahame Grieve (Jun 17 2019 at 04:39):

not clear how a value set provides an ordinal. More generally, is there any validity in a value set defining properties for the codes it references....

view this post on Zulip Grahame Grieve (Jun 17 2019 at 04:40):

we've said that ordinals may be defined in valuesets

view this post on Zulip Robert McClure (Jun 21 2019 at 14:06):

@Grahame Grieve
Help me track the discussion a bit. Here is how I have always thought of the parts going together:

  • Value set CLD identifies concepts for expansion inclusion using
    • concept properties or relationship data defined in the base code system, and/or
    • concept properties (ordinal or otherwise) or relationship data defined in a code system supplement (that can be crafted by anyone)
  • I think we have allowed, but do not understand how to, define a new value set specific concept property (relations too? - like a new hierarchy?) within the CLD for a specified code. By this I mean enumerate a set of codes in the include and give each of the codes value set specific properties valid only in the context of an expand for this value set.
    • Is this what you are discussing?

What we have not clearly defined, or I don't understand, is how to

  • specify a concept property only on the results of the expansion membership, ie: associate an ordinal value to only the values in the value set expansion based on being in the expansion

Then, how do you get the content used above to show up in an expansion? Also, we don't have any way that I know of to specify that everyexpansion of a value set would have specific concept properties included in the expand, correct?

view this post on Zulip Grahame Grieve (Jun 21 2019 at 20:04):

Value set CLD identifies concepts for expansion inclusion

why CLD? why not the request for the expansion itself. The CLD defines what's in the value set, but the system using the value set knows what properties it wants

how to, define a new value set specific concept property (relations too?

yes, that's one of things on my list

is how to specify a concept property only on the results of the expansion membership

That's also on the list above

view this post on Zulip Grahame Grieve (Jun 21 2019 at 20:04):

how do you get the content used above to show up in an expansion

that's the primary todo - extend expansion to cover that

view this post on Zulip Robert McClure (Jun 27 2019 at 14:14):

why CLD? why not the request for the expansion itself.

I assume you didn't follow my point. The CLD uses concept identity, properties, relations, etc. to determine expansion concept membership. I think you are questioning what properties, etc. for those concepts that would also be included in the expansion, and I agree that we don't currently use what is in the CLD to determine what other than concept codes are in the expansion. Is that your point?

that's the primary todo - extend expansion to cover that

Good.

view this post on Zulip Paul Lynch (Jun 27 2019 at 14:44):

At least for my own purposes, I am using $expand with the filter parameter to determine what comes back in the expansion. I don't see how the CLD has any bearing on what I am doing (though there are likely other use cases for it). With regard to properties, I would like to:
1) Specify in the $expand which properties get returned
2) Specify in the $expand which properties are matched via the filter parameter (in addition to the display values)

view this post on Zulip Grahame Grieve (Jun 27 2019 at 20:31):

I assume you didn't follow my point. The CLD uses concept identity, properties, relations, etc. to determine expansion concept membership

ah yes. you're right.

view this post on Zulip Robert McClure (Jun 28 2019 at 16:48):

@Paul Lynch Since you are at the NLM (where?) we should chat directly, offline. PM me. I'm sure I don't understand what you really mean with

I am using $expand with the filter parameter to determine what comes back in the expansion. I don't see how the CLD has any bearing on what I am doing

Because $expand primarily exists to run the CLD for an existing ValueSet resource as an operation. Are you saying you are using $expand without specifying a ValueSet resource you are expanding?

view this post on Zulip Paul Lynch (Jun 28 2019 at 17:00):

@Robert McClure Ha! I did not realize you were also at NLM! It's a small world (or a large NLM). I did not mean to say the CLD was not necessary. I will follow up with a PM.

view this post on Zulip Michael Lawley (Jun 28 2019 at 22:55):

@Paul Lynch for your #2, it sounds like you're describing the CLD, or in FHIR terms, the ValueSet.compose. In this case you would not use the filter parameter, that is explicitly and only for matching designations, but instead POST your own ValueSet definition with whatever property constraints you want directly to the /ValueSet/$expand operation.

view this post on Zulip Paul Lynch (Jun 28 2019 at 23:00):

I'm not sure how that would work. In #2, I am trying to fetch expansion results for a ValueSet for which I only have the URI and some property names. I don't see how I could POST a definition for it. My purpose here is to support autocompletion as the user types in a field in a Questionnaire with answerValueSet.

view this post on Zulip Michael Lawley (Jun 29 2019 at 23:19):

I presume you also have the CodeSystem URI? Let's say it is http://example.com/cs1, the ValueSet URI is http://example.com/vs1, the text entered by the user is "foo" and there is one property of interest "myprop", then you would construct ValueSet with a compose like:

  "compose": {
    "include": [
      {
        "system": "http://example.com/cs1",
        "filter": [
          {
            "property": "myprop",
            "op": "regex",
            "value": "foo.*"
          }
        ],
        "valueSet": [
          "http://example.com/vs1"
        ]
      }
    ]
  },

Which is a CLD for the intersection of the codes with a matching property and those in the ValueSet.
If you have multiple properties or you also want to match against the display text, then add extra include clauses.

view this post on Zulip Robert McClure (Jul 01 2019 at 17:38):

I'll add that in an $expand you could ask for anything that is available from the code system which obviously is likely much more than what was used in the CLD to determine expansion concept membership. One of the interesting thought experiments is if you could even add additional properties to the expand return based on somehow adding in to the $expand, use of a code system supplement.

view this post on Zulip Paul Lynch (Jul 01 2019 at 20:48):

The context I'm working in is Questionnaire, so I don't have a CodeSystem, but a ValueSet URI from Quesitonnaire.item.answerValueSet, and potentially some property names from the choiceColumn extension. The ValueSet the client is being asked to expand might be an already constrained subset of the codes of the CodeSystem, so in general, even if I had a CodeSystem URI, I could not POST my own ValueSet consisting only of the system and the filters I wanted.

With this scheme, I would first have to request the ValueSet resource (not expanded), edit it to add filters for matching the user's input to whichever properties were requested (by choiceColumn) and the POST the result back to server with an $expand. Does that sound correct? Granted, I would only have to request the ValueSet definition once per ValueSet.

I think it could work, but it does not seem simple or elegant.

view this post on Zulip Brian Postlethwaite (Jul 01 2019 at 22:31):

A valueset can depend on another valueset rather than a code system, but that still depends on you being able to create a new valueset (and cleanup after) or submit the whole valueset each time you want to expand (which could be a lot during data entry on an auto complete style field.
And my terminology server does pre expansion, so wouldn't work very well like this.

view this post on Zulip Peter Jordan (Jul 01 2019 at 22:40):

Apologies if I've missed something here - but it might be helpful to have an example of an underlying code system in this use case. If you are attempting to use filters based on properties, these must belong to a Code System (see ValueSet.compose.filter) and that Code System may have a grammar (e.g. ECL in SNOMED CT) that would enable you to make interactive $expansion requests directly to a Terminology Server without the intermediate step of posting ValueSet definitions.

view this post on Zulip Paul Lynch (Jul 01 2019 at 22:55):

@Brian Postlethwaite Thanks-- I had not noticed that a ValueSet could depend on another ValueSet. That is a much better picture, assuming I can post the new valueset along with the $expand. Creating it ahead of time and then cleaning up afterward would mean three requests, or a batch of three requests. I wonder how many terminology servers will have similar problems.

view this post on Zulip Brian Postlethwaite (Jul 01 2019 at 22:58):

And posting it each time is going to get pretty heavy.

view this post on Zulip Brian Postlethwaite (Jul 01 2019 at 23:00):

Would mean that simple terminology servers like mine would be out, and depend on pure terminology servers.

view this post on Zulip Michael Lawley (Jul 01 2019 at 23:08):

The fragment I posted above re-uses the existing bound valueset (vs1) and adds additional constraints. It depends on the terminology server having access to that valueset, of course.
There are performance considerations; POSTs cannot be cached in the HTTP layer, but they can be cached in the terminology server layer (Ontoserevr will do this, for example).

view this post on Zulip Michael Lawley (Jul 01 2019 at 23:10):

What concerns me more, however, is the use-case. If the bindings in the Questionnaire are not in your control, then how do you know it is valid to search against additional properties in the Code System(s) of the underlying bound ValueSet?

view this post on Zulip Michael Lawley (Jul 01 2019 at 23:13):

Picking up on @Peter Jordan s comment, this may be a situation where a general purpose implicit ValueSet syntax akin to SNOMED's ECL may be useful.
On the other hand, if its specific to a particular CodeSystem like LOINC and its answersets, then it may be that teh FHIR Spec should define specific searching behaviour beyond the normal defaults

view this post on Zulip Michael Lawley (Jul 01 2019 at 23:53):

@Brian Postlethwaite your terminology server could always fall back to an externalised service in such a case.

view this post on Zulip Paul Lynch (Jul 02 2019 at 14:22):

Whether a grammar would be helpful or not I'm not sure, but the current mechanism for specifying properties to include (for display to the user, and perhaps for the search) is through the choiceColumn extension. The documentation for that extension is not very helpful, but it is better described on the (SDC rendering page](http://build.fhir.org/ig/HL7/sdc/rendering.html#additional-display-content). There does not seem to be any consideration for hierarchical properties, so I think at this point a grammar is not needed (but the problem will eventually arise).

Anyway, to answer @Michael Lawley 's question, the choiceColumn extension is what tells me it is valid (and required) to request those additional properties. The client does not make up additional properties to search; is comes from the Questionnaire definition.

view this post on Zulip Paul Lynch (Jul 02 2019 at 14:29):

I see @Michael Lawley actually asked about the validity of searching against those properties, not just requesting them. I think it is generally desirable, in an autocompletion setting, to be searching against any properties that are showing up in the list being shown to the user. I suppose the client could check the compatibility statement to see what was allowed? Or maybe it would just try it and fall back to searching in the display value.

view this post on Zulip Xiaocheng Luan (Jul 05 2019 at 14:44):

Brian Postlethwaite Thanks-- I had not noticed that a ValueSet could depend on another ValueSet. That is a much better picture, assuming I can post the new valueset along with the $expand. Creating it ahead of time and then cleaning up afterward would mean three requests, or a batch of three requests. I wonder how many terminology servers will have similar problems.

It appears that the "filter" is not applicable to valueSet within compose.include?

view this post on Zulip Lloyd McKenzie (Jul 05 2019 at 15:52):

It should be...

view this post on Zulip Yunwei Wang (Jul 05 2019 at 15:59):

@Xiaocheng Luan which filter parameter?

view this post on Zulip Xiaocheng Luan (Jul 05 2019 at 17:31):

Xiaocheng Luan which filter parameter?

Good question - I wasn't clear - I meant the compose.include.filter for the use case/example of creating a ValueSet resource and send to server with the $expand request. But yes, $expand request filter parameter should still work. @Lloyd McKenzie

view this post on Zulip Michael Lawley (Jul 07 2019 at 22:45):

If your compose.include has both a filter and a valueset, then it is asking for the set of concepts that are in the referenced valueset and match the system & filter. That is, the filter further constrains the valueset.

view this post on Zulip Brian Postlethwaite (Oct 03 2019 at 03:13):

Outcomes:

  1. define a way to put properties in expansions in R5 (match the CodeSystem pattern)
  2. define an extension to put properties in expansions in R4 (matching the CodeSystem pattern)
  3. define a way for a client to ask for particular properties in expansions : property string 0..* a code or a URI for a property that the client wishes to be returned (or *)
  4. define a way for a value set to specify the default returned properties
  5. document the use of :in to search by property value
  6. define a way for a value set to specify the order if filtered based on properties

Where did we get to with defining this in R5, and was there a format for R4 to expose the properties/extensions in the valueset expansion?

view this post on Zulip Brian Postlethwaite (Oct 03 2019 at 05:08):

@Michael Lawley , think this is something that could be investigated at your NHS Terminology Connectathon?

view this post on Zulip Grahame Grieve (Oct 03 2019 at 05:08):

I'll try and work on a draft for this next week.

view this post on Zulip Grahame Grieve (Oct 03 2019 at 05:09):

might be time to define a ConceptDefinition data type that is used in both CodeSystem (same as what there is now) and also in ValueSet expansion

view this post on Zulip Brian Postlethwaite (Oct 03 2019 at 06:51):

Thanks, I'll be happy to do some POC code for it in R4 when you have a technique done.

view this post on Zulip Michael Lawley (Oct 03 2019 at 11:39):

This topic is something that came up during the 1st day of the connectathon.

The main requirement articulated was the desire to be able to ask for "all properties", e.g., with ?property=*

This raises the question of which properties this would automatically include. For example, parent and child (in some cases child could be very large).

view this post on Zulip Rob Hausam (Oct 03 2019 at 11:49):

@Grahame Grieve Can you elaborate a bit more on the ConceptDefinition data type and how you envision it working?

view this post on Zulip Grahame Grieve (Oct 03 2019 at 19:58):

ConceptDefinition is presently a type defined as part of the CodeSystem resource:

view this post on Zulip Grahame Grieve (Oct 03 2019 at 19:59):

code | display | definition + designation + property

view this post on Zulip Grahame Grieve (Oct 03 2019 at 20:00):

.. nah, the two boolean flags means that a trick that won't work. Will have to clone properties onto the Contains type in value set.

view this post on Zulip Grahame Grieve (Oct 17 2019 at 21:19):

ok I am committing parts 2,4 and 5. part 3 falls out implicitly because of http://build.fhir.org/versions.html#extensions. So that leaves 6 and 7. I don't even remember what either of them are in detail

view this post on Zulip Michael Lawley (Oct 17 2019 at 21:32):

7 I think, was about getting the expansion contents back ordered based on a property value - @Brian Postlethwaite ?

view this post on Zulip Grahame Grieve (Oct 17 2019 at 21:35):

well, there could be all sorts of sophistication there... it feels like a whole little language to itself.... But why property based? Wouldn't you want to do it with any intensional value set?

But why would we standardise this? is there a sweet spot?

view this post on Zulip Michael Lawley (Oct 17 2019 at 21:35):

6 was about something like code:in=valueset.map(c -> c.property) ie. not matching code against the expansion concepts, but instead against a property of the expansion's concepts

view this post on Zulip Michael Lawley (Oct 17 2019 at 21:36):

I'm not convinced about 7 -- I suspect most cases could be handled by sorting client-side

view this post on Zulip Grahame Grieve (Oct 17 2019 at 21:37):

both 6 and 7 sound deliciously complicated

view this post on Zulip Michael Lawley (Oct 17 2019 at 21:57):

indeed. 6 is somewhat related to the desire to match against code translations.
i.e., say your retrieval valueset vsUri is defined in terms of ICD10 and your data has a mix of ICD10 and SNOMED and you have an appropriate conceptmap cmUri from SNOMED to ICD10. You want to be able to say something like ?code:translate(cmUri):in=vsUri

view this post on Zulip Michael Lawley (Oct 17 2019 at 22:05):

Re 3, this means in R4 we would add (complex) extensions to ValueSet.expansion.contains with the URI http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property? What are the URI's of the nested pieces? code and value or http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property.code and http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property.value ?

view this post on Zulip Grahame Grieve (Oct 17 2019 at 22:14):

first, I think - simple because they are part of how the extension is defined. But I'm not sure we discussed that explicitly

view this post on Zulip Grahame Grieve (Oct 17 2019 at 22:28):

one thing that comes out of this... we need revisit our definitions of properties. It's all a bit messed up

view this post on Zulip Michael Lawley (Oct 17 2019 at 22:52):

How do relative URIs in nested extensions get resolved against the absolute parent URI in an extension. It doesn't seem to work using normal URI resolution rules because the resolved URI for the inner extension in :

  <extension url="http://hl7.org/fhir/StructureDefinition/patient-citizenship" >
    <extension url="code" >
    ...

would be http://hl7.org/fhir/StructureDefinition/code but I strong suspect the intension is that it's something like http://hl7.org/fhir/StructureDefinition/patient-citizenship/code

view this post on Zulip Michael Lawley (Oct 17 2019 at 22:55):

The spec (http://build.fhir.org/versions.html#extensions) says this:

Where complex data types have no equivalent in an earlier version, use a complex extension, containing extensions also following this pattern.

Which I can only interpret as requiring use of absolute URIs in the nested extension elements.

view this post on Zulip Grahame Grieve (Oct 18 2019 at 02:36):

yes I guess it does

view this post on Zulip Brian Postlethwaite (Oct 18 2019 at 03:27):

6 and 7 weren't in my list of what I was after, just the other ones.
So if there is something to handle that part, i'm good to go and try things out.

view this post on Zulip Grahame Grieve (Oct 18 2019 at 03:28):

I'm just wrangling with the validator - will be out in the next 24 hours

view this post on Zulip Brian Postlethwaite (Oct 18 2019 at 03:28):

No stress, thanks.

view this post on Zulip Michael Lawley (Oct 18 2019 at 05:50):

I'm away that Genomics England have the translate use-case, and it has also come up with UK NHS in the context of maps that deal with code replacement (eg as provided by SNOMED). But then there's the replacedBy property which is another way of tackling this problem.

view this post on Zulip Grahame Grieve (Oct 18 2019 at 12:08):

so just to be clear about this, some example extensions in R4:

  <compose>
    <include>
      <system value="http://hl7.org/fhir/CodeSystem/example"/>
    </include>
    <extension url="http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.compose.property">
      <valueString value="status"/>
   </extension>
  </compose>

view this post on Zulip Grahame Grieve (Oct 18 2019 at 12:09):

that's request for a property in the expansion. And then in expansion (in json):

view this post on Zulip Grahame Grieve (Oct 18 2019 at 12:15):

"expansion": {
  "extension": [{
    "url": "http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.property",
    "extension" : [{
      "url" : "http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.property.code",
      "valueCode": "PROPERTY"
    },{
      "url" : "http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.property.uri",
      "valueUri": "http://loinc.org/property/PROPERTY"
    }]
  }],
  "contains": [{
    "system": "http://loinc.org",
    "version": "2.50",
    "code": "14647-2",
    "display": "Cholesterol [Moles/volume] in Serum or Plasma",
    "extension": [{
      "url": "http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property",
      "extension" : [{
        "url" : "http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property.code",
        "valueCode": "PROPERTY"
      },{
        "url" : "http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property.value[x]",
        "valueCode": "SCnc"
      }]
    }]
  },
  ...

view this post on Zulip Michael Lawley (Feb 17 2020 at 03:41):

@Grahame Grieve I'd like to start on pre-adoption of R5's properties in expansion results, but I'm concerned that 5.0 is not likely to work and that I may perhaps need to use 4.2 ?

view this post on Zulip Grahame Grieve (Feb 17 2020 at 03:43):

I

view this post on Zulip Grahame Grieve (Feb 17 2020 at 03:43):

I'm not exactly sure what you you are asking there

view this post on Zulip Michael Lawley (Feb 17 2020 at 21:53):

Given that the (pre-)R5 version is 4.2.0, should I be using http://hl7.org/fhir/4.2/StructureDefinition/extension-ValueSet.expansion.contains.property.code? That is, is there anything in the stack (validation?) that interprets these URIs?

view this post on Zulip Grahame Grieve (Feb 17 2020 at 23:24):

no. R5 extensions are not in the validator framework right now

view this post on Zulip Grahame Grieve (Feb 17 2020 at 23:25):

by any version

view this post on Zulip Paul Lynch (Aug 28 2020 at 23:32):

Brian Postlethwaite said:

Outcomes:

  1. define a way to put properties in expansions in R5 (match the CodeSystem pattern)
  2. define an extension to put properties in expansions in R4 (matching the CodeSystem pattern)
  3. define a way for a client to ask for particular properties in expansions : property string 0..* a code or a URI for a property that the client wishes to be returned (or *)
  4. define a way for a value set to specify the default returned properties
  5. document the use of :in to search by property value
  6. define a way for a value set to specify the order if filtered based on properties

Where did we get to with defining this in R5, and was there a format for R4 to expose the properties/extensions in the valueset expansion?

Are there tracker items for these things? I am just wondering whether this exists somewhere outside this thread, so it doesn't get lost.

view this post on Zulip Brian Postlethwaite (Aug 31 2020 at 21:59):

And can we add it to the connectathon stream for R4?

view this post on Zulip Brian Postlethwaite (Sep 10 2020 at 18:21):

Hey all, going to do some testing on this, did an implementation of the back-port (expansion results) and wanted to run it past folks.

view this post on Zulip Grahame Grieve (Sep 10 2020 at 18:31):

ok

view this post on Zulip Brian Postlethwaite (Sep 10 2020 at 19:50):

How does this look to represent the contains property in the returned results in R4?
Based on the def from http://build.fhir.org/valueset.html

  <expansion>
    <contains>
      <extension url="http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property">
        <extension url="code">
          <valueCode value="custom-code-prop" />
        </extension>
        <extension url="value"> <!-- or should this be value[x]-->
          <valueString value="custom-code-value" />
        </extension>
      </extension>
      <system value="urn:ietf:bcp:47" />
      <code value="de-AT" />
      <display value="German (Austria)" />
    </contains>
    <contains>
      <system value="urn:ietf:bcp:47" />
      <code value="de-CH" />
      <display value="German (Switzerland)" />
    </contains>

view this post on Zulip Brian Postlethwaite (Sep 10 2020 at 19:56):

Sorry, just updated based on notes further up that I'd missed.
any reason why using the full URLs and not just simple values (as in with a complex extension?)

view this post on Zulip Brian Postlethwaite (Sep 10 2020 at 20:02):

And I don't see any changes to the R4 expand operation to ask for them either?
Do we actually need to compose another valueset that expands the existing valueset and indicate that you want the properties back, and post that?

view this post on Zulip Grahame Grieve (Sep 10 2020 at 20:03):

no we would just pre-adopt R5 parameters in R4

view this post on Zulip Brian Postlethwaite (Sep 10 2020 at 20:04):

Sorry, missed the property parameter. My mistake.

view this post on Zulip Brian Postlethwaite (Sep 10 2020 at 20:06):

On that backbone element child property extension URLs, any reason for the full name and not just the short one within the context of the fully described parent?
ie. http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property.code and not just code

view this post on Zulip Grahame Grieve (Sep 10 2020 at 20:06):

or should this be value[x]

yes

view this post on Zulip Grahame Grieve (Sep 10 2020 at 20:07):

no. it's worse.

view this post on Zulip Grahame Grieve (Sep 10 2020 at 20:07):

value_x_

view this post on Zulip Brian Postlethwaite (Sep 10 2020 at 20:09):

This is where I should be looking right?
http://build.fhir.org/versions.html#extensions
There is nothing in there on backbone elements, nor value[x]

view this post on Zulip Grahame Grieve (Sep 10 2020 at 20:09):

well, there is by implication on the second:

view this post on Zulip Grahame Grieve (Sep 10 2020 at 20:10):

The [Path] is actually the ElementDefinition.id from the relevant StructureDefinition for the element

view this post on Zulip Grahame Grieve (Sep 10 2020 at 20:11):

Agree that there's nothing about backbone elements, to my surprise. Agree that the way you've done it is right.

view this post on Zulip Grahame Grieve (Sep 10 2020 at 20:12):

would be good to make a task on both these - to point out how value[x[ works, and to agree about backbone elemnets

view this post on Zulip Brian Postlethwaite (Sep 10 2020 at 20:13):

Will do, I'm looking to try and find where the value_x_ for elementdef.id is documented

view this post on Zulip Brian Postlethwaite (Sep 10 2020 at 20:20):

@Michael Lawley , did this ever make it into your R4 builds yet?

view this post on Zulip Grahame Grieve (Sep 10 2020 at 20:33):

you have to look inside the structure definition itself

view this post on Zulip Brian Postlethwaite (Sep 10 2020 at 20:54):

J#28479

view this post on Zulip Michael Lawley (Sep 10 2020 at 22:29):

As I read the spec, the reason for full URIs is that this:

any element defined in any version of FHIR is automatically assigned an extension URL that uniquely identifies the element

So code and value[x] have their own URIs:

  • http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property.code
  • http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property.value_x_

AFAICT, this is not the same as having a complex extension defined and then being able to use child extension references.

view this post on Zulip Michael Lawley (Sep 10 2020 at 22:39):

I don't know if there's any infrastructure code that will take, for example, an R5 ValueSet and transform it to the R4 version with extensions?

view this post on Zulip Michael Lawley (Sep 10 2020 at 22:40):

I'm not sure that we have real clarity here, which is one reason why we haven't merged expansion properties into the Ontoserver dev build yet.
However, if J#28479 is likely to be accepted as proposed, then I'd be comfortable to bring it in, although the window for the next release is rapidly closing.

view this post on Zulip Brian Postlethwaite (Sep 11 2020 at 00:17):

I'm going to draft this into my server today to try it out with some questionnaire stuff we're doing.

view this post on Zulip Brian Postlethwaite (Sep 11 2020 at 05:30):

Have implemented and deployed this into my server now too.

view this post on Zulip Robert McClure (Sep 12 2020 at 19:43):

@Brian Postlethwaite IF this is working on your server, any chance you have rxnorm installed with all it's properties? And I can access it?

view this post on Zulip Brian Postlethwaite (Sep 12 2020 at 20:14):

My server isn't anywhere near that complex. Just simple stuff manually loaded in via fhir.

view this post on Zulip Grahame Grieve (Sep 13 2020 at 10:20):

what properties would you care about for RxNorm?

view this post on Zulip Brian Postlethwaite (Sep 13 2020 at 21:37):

Now that I've done it, this same extension structure could be used on a coding too.
I'm looking for a way to reference the property in a questionnaire without hitting the terminology server again.
Some notes on the connectathon report out. Will follow up again later.
https://confluence.hl7.org/pages/viewpage.action?pageId=86974609#id-202009Questionnaire-Notableachievements:

view this post on Zulip Grahame Grieve (Sep 13 2020 at 22:17):

well, not so easy, because the code is relative to the definition of it.

view this post on Zulip Brian Postlethwaite (Sep 14 2020 at 06:36):

Since this is probably what people might find later if searching here for it, you should also include the valueset.expansion.property in the extensions too ensuring that the declaration of what properties were asked for and included in the output explicitly.
Here is an example of it
https://sqlonfhir-r4.azurewebsites.net/fhir/ValueSet/45/$expand?property=s-val

view this post on Zulip Michael Lawley (Sep 14 2020 at 09:58):

Hmm, I ended up with the following for ValueSet/$expand?url=http://snomed.info/sct?fhir_vs=ecl/>>33015000&property=moduleId&property=effectiveTime&property=parent (which is different):

<ValueSet xmlns="http://hl7.org/fhir">
    <language value="en"/>
    <url value="http://snomed.info/sct/32506021000036107/version/20200531?fhir_vs=ecl%2F%3E%3E33015000"/>
    <name value="SNOMED CT ECL expression"/>
    <status value="active"/>
    <experimental value="false"/>
    <copyright value="This value set includes content from SNOMED CT, which is copyright © 2002+ International Health Terminology Standards Development Organisation (IHTSDO), and distributed by agreement between IHTSDO and HL7. Implementer use of SNOMED CT is not covered by this agreement"/>
    <expansion>
        <extension url="http://hl7.org/fhir/StructureDefinition/valueset-unclosed">
            <valueBoolean value="true"/>
        </extension>
        <identifier value="9811e09e-d2f7-4b61-b8d5-51d0343f3750"/>
        <timestamp value="2020-09-14T19:54:29+10:00"/>
        <total value="54"/>
        <offset value="0"/>
        <parameter>
            <name value="version"/>
            <valueUri value="http://snomed.info/sct|http://snomed.info/sct/32506021000036107/version/20200531"/>
        </parameter>
        <parameter>
            <name value="count"/>
            <valueInteger value="2147483647"/>
        </parameter>
        <parameter>
            <name value="offset"/>
            <valueInteger value="0"/>
        </parameter>
        <contains>
            <extension url="http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property">
                <extension url="parent">
                    <valueCode value="108191006"/>
                </extension>
                <extension url="parent">
                    <valueCode value="118869008"/>
                </extension>
                <extension url="parent">
                    <valueCode value="83607001"/>
                </extension>
                <extension url="parent">
                    <valueCode value="120200004"/>
                </extension>
                <extension url="effectiveTime">
                    <valueString value="20020131"/>
                </extension>
                <extension url="moduleId">
                    <valueString value="900000000000207008"/>
                </extension>
            </extension>
            <system value="http://snomed.info/sct"/>
            <code value="120058006"/>
            <display value="Fallopian tube endoscopy"/>
        </contains>
        <contains>
            <extension url="http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property">
                <extension url="parent">
                    <valueCode value="108193009"/>
                </extension>
                <extension url="parent">
                    <valueCode value="392250009"/>
                </extension>
                <extension url="parent">
                    <valueCode value="45835000"/>
                </extension>
                <extension url="parent">
                    <valueCode value="363068004"/>
                </extension>
                <extension url="parent">
                    <valueCode value="128422009"/>
                </extension>
                <extension url="effectiveTime">
                    <valueString value="20110131"/>
                </extension>
                <extension url="moduleId">
                    <valueString value="900000000000207008"/>
                </extension>
            </extension>
            <system value="http://snomed.info/sct"/>
            <code value="447192001"/>
            <display value="Electrodestruction of fallopian tube"/>
        </contains>

view this post on Zulip Brian Postlethwaite (Sep 14 2020 at 10:36):

There is no property parent on that backbone element.

view this post on Zulip Brian Postlethwaite (Sep 14 2020 at 10:38):

parent in your example here is a code value in the code child complex extension, the value Code value is to the value_x_ extension

view this post on Zulip Brian Postlethwaite (Sep 14 2020 at 10:40):

And it's missing the property child directly under expansion which lists the code to Uri for the properties included.

view this post on Zulip Michael Lawley (Sep 14 2020 at 10:44):

ah, of course, now I get the model - thanks!

view this post on Zulip Brian Postlethwaite (Sep 14 2020 at 10:45):

Can you see the example from my server for comparison?

view this post on Zulip Michael Lawley (Sep 14 2020 at 11:01):

So this is what I have now:

<ValueSet xmlns="http://hl7.org/fhir">
    <language value="en"/>
    <url value="http://snomed.info/sct/32506021000036107/version/20200531?fhir_vs=ecl%2F%3E%3E33015000"/>
    <name value="SNOMED CT ECL expression"/>
    <status value="active"/>
    <experimental value="false"/>
    <copyright value="This value set includes content from SNOMED CT, which is copyright © 2002+ International Health Terminology Standards Development Organisation (IHTSDO), and distributed by agreement between IHTSDO and HL7. Implementer use of SNOMED CT is not covered by this agreement"/>
    <expansion>
        <extension url="http://hl7.org/fhir/StructureDefinition/valueset-unclosed">
            <valueBoolean value="true"/>
        </extension>
        <identifier value="b41ab029-ac70-41f2-919a-35993e46b1af"/>
        <timestamp value="2020-09-14T21:19:09+10:00"/>
        <total value="54"/>
        <offset value="0"/>
        <parameter>
            <name value="version"/>
            <valueUri value="http://snomed.info/sct|http://snomed.info/sct/32506021000036107/version/20200531"/>
        </parameter>
        <parameter>
            <name value="count"/>
            <valueInteger value="2"/>
        </parameter>
        <parameter>
            <name value="offset"/>
            <valueInteger value="0"/>
        </parameter>
        <contains>
            <extension url="http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property">
                <extension url="code">
                    <valueCode value="parent"/>
                </extension>
                <extension url="value_x_">
                    <valueCode value="108191006"/>
                </extension>
            </extension>
            <extension url="http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property">
                <extension url="code">
                    <valueCode value="parent"/>
                </extension>
                <extension url="value_x_">
                    <valueCode value="118869008"/>
                </extension>
            </extension>
            <extension url="http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property">
                <extension url="code">
                    <valueCode value="parent"/>
                </extension>
                <extension url="value_x_">
                    <valueCode value="83607001"/>
                </extension>
            </extension>
            <extension url="http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property">
                <extension url="code">
                    <valueCode value="parent"/>
                </extension>
                <extension url="value_x_">
                    <valueCode value="120200004"/>
                </extension>
            </extension>
            <extension url="http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property">
                <extension url="code">
                    <valueCode value="effectiveTime"/>
                </extension>
                <extension url="value_x_">
                    <valueString value="20020131"/>
                </extension>
            </extension>
            <extension url="http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property">
                <extension url="code">
                    <valueCode value="moduleId"/>
                </extension>
                <extension url="value_x_">
                    <valueString value="900000000000207008"/>
                </extension>
            </extension>
            <system value="http://snomed.info/sct"/>
            <code value="120058006"/>
            <display value="Fallopian tube endoscopy"/>
        </contains>
        <contains>
            <extension url="http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property">
                <extension url="code">
                    <valueCode value="parent"/>
                </extension>
                <extension url="value_x_">
                    <valueCode value="108193009"/>
                </extension>
            </extension>
            <extension url="http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property">
                <extension url="code">
                    <valueCode value="parent"/>
                </extension>
                <extension url="value_x_">
                    <valueCode value="392250009"/>
                </extension>
            </extension>
            <extension url="http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property">
                <extension url="code">
                    <valueCode value="parent"/>
                </extension>
                <extension url="value_x_">
                    <valueCode value="45835000"/>
                </extension>
            </extension>
            <extension url="http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property">
                <extension url="code">
                    <valueCode value="parent"/>
                </extension>
                <extension url="value_x_">
                    <valueCode value="363068004"/>
                </extension>
            </extension>
            <extension url="http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property">
                <extension url="code">
                    <valueCode value="parent"/>
                </extension>
                <extension url="value_x_">
                    <valueCode value="128422009"/>
                </extension>
            </extension>
            <extension url="http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property">
                <extension url="code">
                    <valueCode value="effectiveTime"/>
                </extension>
                <extension url="value_x_">
                    <valueString value="20110131"/>
                </extension>
            </extension>
            <extension url="http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property">
                <extension url="code">
                    <valueCode value="moduleId"/>
                </extension>
                <extension url="value_x_">
                    <valueString value="900000000000207008"/>
                </extension>
            </extension>
            <system value="http://snomed.info/sct"/>
            <code value="447192001"/>
            <display value="Electrodestruction of fallopian tube"/>
        </contains>
    </expansion>
</ValueSet>

view this post on Zulip Brian Postlethwaite (Sep 14 2020 at 11:05):

That's extensive :laughing:

view this post on Zulip Michael Lawley (Sep 14 2020 at 11:06):

WIP -- I posted then noticed a bug! - no way to delete the message AFAICT

view this post on Zulip Michael Lawley (Sep 14 2020 at 11:20):

how's that?

view this post on Zulip Brian Postlethwaite (Sep 14 2020 at 21:41):

That's good, and to complete just needs the extension for the valueset.expansion.property to declare the full Uri for the property codes from the CodeSystem and its the same as what I've done.

view this post on Zulip Michael Lawley (Sep 14 2020 at 22:51):

Hmm, interesting. Why do properties get re-declared in the expansion?

view this post on Zulip Brian Postlethwaite (Sep 15 2020 at 00:05):

Isn't that to provide what the canonical URI is for the code declaration is that is in the concepts in the expansion?

view this post on Zulip Brian Postlethwaite (Sep 15 2020 at 00:05):

(It's in the R5 valueset definition)

view this post on Zulip Michael Lawley (Sep 15 2020 at 00:08):

I see it in the R5 definition, but doesn't this duplicate the declaration from the CodeSystem?

view this post on Zulip Grahame Grieve (Sep 15 2020 at 00:09):

it's not the code system

view this post on Zulip Michael Lawley (Sep 15 2020 at 00:10):

Sure, but the CodeSystem already includes this information (and presumably it is the actual source of it). I'm wondering what the need is to replicate it?

view this post on Zulip Grahame Grieve (Sep 15 2020 at 00:11):

we didn't - and couldn't - make a rule that the code must match

view this post on Zulip Michael Lawley (Sep 15 2020 at 00:12):

meaning that the CS make declare http://example.com/prop/foo and foo but the VS expansion may have http://example.com/prop/foo and bar ?

view this post on Zulip Grahame Grieve (Sep 15 2020 at 00:12):

it could. yes.

view this post on Zulip Michael Lawley (Sep 15 2020 at 00:14):

So all clients need to reconcile the actual property code back to the property URI?
When is this needed? (for the VS to use different property codes to the CS?)

view this post on Zulip Grahame Grieve (Sep 15 2020 at 00:20):

because an expansion can cover multiple code systems, and the code systems could define clashing property codes (which is why they also define URIs)

view this post on Zulip Michael Lawley (Sep 15 2020 at 02:14):

But...you know which system any given concept is from, so the property code is always relative to that system

view this post on Zulip Grahame Grieve (Sep 15 2020 at 02:14):

that's true

view this post on Zulip Grahame Grieve (Sep 15 2020 at 02:17):

so you're effectively proposing that we should say that properties in expansions always SHALL use the code defined for the property in the code system, and the property code in the expansion is scoped by the system

view this post on Zulip Michael Lawley (Sep 15 2020 at 02:25):

yes, very much so. otherwise you're pushing significant additional complexity onto clients

view this post on Zulip Grahame Grieve (Sep 15 2020 at 02:29):

I don't know that we are. We're just moving the resolution to URI from the expansion to the code system.

view this post on Zulip Brian Postlethwaite (Sep 15 2020 at 02:36):

and forcing the lookup back to the codesystem too by the client as a seperate action.

view this post on Zulip Michael Lawley (Sep 15 2020 at 02:38):

If it's fixed in the CodeSystem, then clients can make assumptions. If it can be varied in the ValueSet, then clients cannot make assumptions.

view this post on Zulip Grahame Grieve (Sep 15 2020 at 02:46):

I think that's over stating it. Under the current system, it's tied to the uri defined in the code system. Michael proposes to change that being tied to the code in the code system. I'm not seeing a very significant change here

view this post on Zulip Brian Postlethwaite (Sep 15 2020 at 03:47):

It's stating that the property URI is meaningless then?

view this post on Zulip Grahame Grieve (Sep 15 2020 at 03:50):

I don't think that's the case; It's still meaningful in other ways even if it's not directly implicated here

view this post on Zulip Michael Lawley (Sep 15 2020 at 06:26):

My concern is whether a client can assume that the property code moduleId in a VS expansion on a SNOMED concept corresponds to the moduleId code as defined for SNOMED. Instead, it needs to check that the associated URI listed in the VS expansion corresponds to that listed in the CS.

view this post on Zulip Michael Lawley (Sep 15 2020 at 06:28):

I note that a $lookup doesn't give you back the property-code -> URI mapping


Last updated: Apr 12 2022 at 19:14 UTC