Stream: shorthand
Topic: Noob questions
Kippi Bordowitz (Jan 23 2021 at 18:15):
Hi All.
I'm brand new to FHIR and even newer to FSH. I'm really trying to teach it to myself but it's hard going. The documentation seems to be geared towards veteran programmers only and while I am a fairly decent one, mostly in python, some of the text I simply cannot understand and honestly, it feels like banging my head against a wall...
Right now I am breaking my brain trying to understand what the caret symbol means. I read it several times but I really need a down to earth explanation. Unfortunately, the tutorial doesn't address this.
Also what is the difference between "^" and ". ^"?
Sorry, i know this probably trivial stuff but I am trying to prove to the Israeli MOH that FSH is the way to go (They have only just begun defining the national core patient) and if I cannot understand it myself, I certainly cannot explain it.
Thanks kindly!
Another thing. the FSH tutorial comes with an automatic publisher. Is it possible to re-use it for any project or is it only meant for the tutorial. I suddenly realize now that when I showed it to people and said "look! there is even a tool that automatically produces the published IG!" I might have been very wrong about this. If this isn't the case, does this mean I must learn all the ins and outs of ig publishing or are there already automatic tools for this kind of thing?
Also, I ran the goFSH tutorial and was surprised to find that not all the info in the original JSON file actually got converted to FSH. A LOT of information. And this is the file made by the tutorial! So where does all that missing information go? How it it decided what stays and what not?
Thank you for your time!
Jean Duteau (Jan 23 2021 at 18:18):
i'll answer the part about the publisher - you can use SUSHI independently to take your FSH files and create inputs for the IG Publisher or just to create profiles, examples, value sets, code systems, etc. that you could use in other projects. Or you can use the IG Publisher which automatically recognizes that you have FSH files (if you have put them in the proper places) and will convert them to FHIR artifacts and then create a full-blown FHIR Implementation Guide.
Kippi Bordowitz (Jan 23 2021 at 20:25):
Ok. Not what I was hoping to hear (unless I missunderstod you, I'm going to have to learn the publisher, no matter if I use fsh or not... right? There is no like... easy to use automated tool. I'm looking at the documentation and it seems like there is quite a lot to learn there).
No answer regarding the "^" vs ".^"? Sorry. It's just - It's been a while since I've felt like a complete idiot :)
Jean Duteau (Jan 23 2021 at 20:27):
it depends on what you are using FSH for. Are you using it to make example FHIR instances? Or are you using it to make FHIR artifacts that will then go into the creation of a FHIR Implementation Guide? If you tell us what you want to use your FSH artifacts for, we can tell you what tools you would need.
Kippi Bordowitz (Jan 23 2021 at 20:29):
To make my question regarding the publisher more coherent - does the publisher produce html and all the different resources that the tutorial publisher produces? I'm talking about creating resources. I want to show the nice people in the ministry of health here that FSH will make the process easier and I want to be able to say - "here, look" and have a ready made page that looks like every other FHIR documentation page. The tutorial came with a built in tool that does that but apparently it's configured very specifically only for the tutorial.
Jean Duteau (Jan 23 2021 at 20:30):
Here are answers to some of your other questions (I was in a meeting so couldn't find links and such and it is the weekend so others are probably busy):
^ https://build.fhir.org/ig/HL7/fhir-shorthand/reference.html#caret-paths. It is used to reference the FHIR item that is going to represent the thing you are creating. So if you are creating a FHIR profile but need to specify pieces of the underlying StructureDefinition that will represent your Profile, you use the ^ path to get to that.
. ^. is a special case for setting properties of the first element of a Structure Definition.
Jean Duteau (Jan 23 2021 at 20:33):
i don't think that the tutorial comes with a built-in tool but I'll confess to not following the tutorial in a long time. When I look at the tutorial on fshschool.org, it uses the regular IG publisher (that is what is being run when you execute the _genonce script).
Jean Duteau (Jan 23 2021 at 20:34):
Step 5 of the tutorial around generating the sample IG is just downloading the regular FHIR IG publisher tool and then running it.
Jean Duteau (Jan 23 2021 at 20:39):
as to GoFSH - there is a lot of FHIR "stuff" that is contained in a StructureDefinition that is extrapolated by the easier syntax of FSH. As an example, a profile StructureDefinition will have both a snapshot and a differential view. Armed with the FSH definition of the profile and the resource definition that the profile is based on, you can generate the snapshot from the differential, so we don't express both of those in FSH. So a lot of the stuff that goes into a Profile StructureDefinition is generated by SUSHI so doesn't have to come across in the FSH file. And that is actually the point of FHIR Shorthand - it means that we as authors don't need to know the syntax of a StructureDefinition unless you need to for more complicated things.
Mark Kramer (Jan 23 2021 at 20:41):
Hello Kippi, the tutorial, walks you through the process of generating a simple implementation guide. If you can get through that successfully, then you can use exactly the same process to produce any IG. As Jean said, it uses the standard IG Publisher tool.
The caret syntax is rather specialized, and to use it, you have to know something about the StructureDefinition resource. It is something like "direct line" to the StructureDefinition. If possible, I would stay away from that until you get comfortable with other parts of the FSH language.
Kippi Bordowitz (Jan 23 2021 at 21:15):
Thanks for all the responses!
regarding the publisher, it came bundled with the tutorial files so maybe that's what threw me off. I'll try installing and see if that will work. Will return with results.
Max Masnick (Jan 24 2021 at 19:19):
@Kippi Bordowitz I often find it helpful to look at examples from other IGs that use FSH. If you haven’t found it already, there’s a list of these IGs here: https://fshschool.org/fsh-finder/
Brian Kaney (Jan 25 2021 at 00:56):
Neato! I didn't know about fsh-finder, thanks @Max Masnick
Kippi Bordowitz (Jan 25 2021 at 12:05):
I disagree regarding what you said about the tutorial. the publisher is already set up automatically. There is no tutorial, that I am aware of, that actually explains how to use it, other than running the _genounce.bat
file. And if I am to understand correctly from reading the documentation, what they use is deprecated. But I'm still trying to wrap my brain around it.
Jose Costa Teixeira (Jan 25 2021 at 13:34):
Not sure it matters What I do to make my own life simpler (after installing the dependencies):
I just have an empty IG structure (as a github template). When I download and run it it generates a working, empty IG.
I use it when I give training - if that thing fails, it's their machine that is broken, not the IG. And this ensures all IGs for a given institution are consistent.
Then, editors just add fsh files, diagrams, pages...
Chris Moesel (Jan 25 2021 at 14:19):
@Kippi Bordowitz -- The FSH Tutorial starter zip comes with publisher scripts that can then download the actual publisher and invoke it. There is not a lot to the scripts except to bootstrap those things. The publisher itself is developed and maintained by the core FHIR team. The scripts/publisher are not deprecated, although the scripts in the tutorial zip might be an older version.
SUSHI now has a feature to create a starter project for you -- so you might find that helpful. Just run sushi --init
and it will build a project structure with a baseline config file, starter FSH file, and the latest versions of the publisher scripts (which are now also self-updating). This is what we recommend for new projects.
You can also always download the latest scripts from here: https://github.com/HL7/ig-publisher-scripts. But if you use sushi --init
and then allow the scripts to self-update whenever you run _updatePublisher
then you shouldn't need to go to the GitHub location.
Kippi Bordowitz (Jan 25 2021 at 14:21):
Cool. Thanks. Will give it a try
Kippi Bordowitz (Jan 25 2021 at 14:43):
OK. Some success!
But the page looks nothing (or not much) like a standard FHIR page. I see all the resources needed for it in the output folder but right now it looks like this ( temp.JPG ).
I have no real experience with front end programming but I have a feeling that it's more a config thing than anything else. Am I right? I am showing this to Israeli ministry of health tomorrow and would love for it to actually resemble other FHIR pages.
Chris Moesel (Jan 25 2021 at 15:17):
The look and feel of the page is controlled by the template. There are several templates you can choose from, based on the type of IG you are creating. Have a look at the Guidance for IG Creation documentation. It lists a set of common templates. Once you identify a template you want to use, you specify it in your project's ig.ini
file. In your case, the hl7.fhir.template
template will give you the look of other FHIR pages -- but note that it really is only appropriate if you will be publishing your IG through HL7. But for a demonstration of what is possible, I'm sure it will be fine. In the future, if you choose, you can even design your own template.
Kippi Bordowitz (Jan 25 2021 at 15:22):
Great. Will give it a look. Thanks again for all your patience!
Kippi Bordowitz (Jan 25 2021 at 15:44):
@Chris Moesel weird. Once I changed the template the _genounce failed. Copied it perfectly.
Chris Moesel (Jan 25 2021 at 15:55):
As for ^
, hopefully some of the remarks above helped, but if not... Think of most of FSH as being a higher-level language for doing common profiling tasks. There is a nice syntax for binding value sets, assigning fixed values, narrowing data types, etc. But it is a higher level language; behind the scenes, it is really creating and manipulating information in the StructureDefinition format.
For example, consider this rule from a profile on Observation
:
* code from SomeValueSet (preferred)
That is shorthand for saying to find (or create) the element in the differential.element
array whose path
is Observation.code
, and then set the binding.valueSet
to the canonical URL of SomeValueSet and set the binding.strength
to preferred
. It would result in a JSON ElementDefinition in the profile StructureDefinition something like this:
{
"id": "Observation.code",
"path": "Observation.code",
"binding": {
"valueSet": "http://example.org/ValueSet/SomeValueSet",
"strength": "preferred"
}
}
Many FSH rules are a lot more complicated than this, but I've intentionally chosen a simple one so you can easily see how the high-level FSH from
rule translated to the formal definition in the StructureDefinition. Notice that you didn't need to know how a binding works in the SD (i.e., you didn't need to know about the binding
object or valueSet
/ strength
properties -- nor did you need to fully write out the canonical URL of the VS). The high-level FSH rules abstract that from you.
BUT... if you did want to manipulate the StructureDefinition more directly, and control the exact values of those exact properties in that element, you could have done this instead:
* code ^binding.valueSet = "http://example.org/ValueSet/SomeValueSet"
* code ^binding.strength = "preferred"
The above ^
rules have the same exact result as the higher-level from
rule. They say to first find the Observation.code
element, and then within that element in the StructureDefinition source, find the binding.valueSet
and binding.strength
properties and set them to the specified values. So you can see, we're going from the higher-level abstract syntax to a lower-level "directly manipulate the actual SD code" syntax.
Of course, when a higher-level approach works, you should use it. So I would never expect someone to do a value set binding like that. So here is an example of a more realistic use... If you look at the ElementDefinition structure, you can see that each element's binding
also supports an optional description
property -- which is not accessible via the higher level FSH syntax (since its use is more rare). If you wanted to set the binding's description
, then your only option is to use the ^
syntax to directly set it in the StructureDefinition. In this case, you might use both a higher-level FSH rule to set the binding value set and strength and a caret rule to set the description:
* code from SomeValueSet (preferred)
* code ^binding.description = "Very special codes I've selected myself"
resulting in:
{
"id": "Observation.code",
"path": "Observation.code",
"binding": {
"valueSet": "http://example.org/ValueSet/SomeValueSet",
"strength": "preferred",
"description": "Very special codes I've selected myself"
}
}
Chris Moesel (Jan 25 2021 at 16:06):
As for the different path syntaxes, using a profile on Observation
as an example:
^publisher = "Acme, Inc."
--> search from the top-level of the StructureDefinition for a property calledpublisher
and set it.. ^short = "My profile short description"
--> find or create the root element in thedifferential.element
array (e.g., w/"path": "Observation"
) and set itsshort
property.code ^short = "My code element short description"
--> find or create the element w/"path": "code"
and set itsshort
property.
Excluding all the other elements (for brevity), your SD would have at least these things based on those rules:
{
"id": "Observation",
"publisher": "Acme, Inc.",
"differential": {
"element": [
{
"id": "Observation",
"path": "Observation",
"short": "My profile short description"
},
{
"id": "Observation.code",
"path": "Observation.code",
"short": "My code element short description"
}
]
}
}
Chris Moesel (Jan 25 2021 at 16:29):
Kippi Bordowitz said:
Chris Moesel weird. Once I changed the template the _genounce failed. Copied it perfectly.
I'm guessing that it's because your IG id
doesn't match the rules that the HL7 FHIR template requires. If you look at the last few lines in the output, you'll probably see an error message something like this:
[xslt] Loading stylesheet /Users/cmoesel/dev/fsh/TestFHIRTemplate/template/scripts/onGenerate.genProperties.xslt
When using the HL7 template, the IG id must start with "hl7." - found fhir.example
The HL7 FHIR template requires the IG id to follow the form: hl7.{family}.{realm}.{id}
. For example: hl7.fhir.uv.example
. To fix this, you need to edit the id in two files:
Within sushi-config.yaml:
id: hl7.fhir.uv.example
Within ig.ini:
ig = fsh-generated/resources/ImplementationGuide-hl7.fhir.uv.example.json
After that it should work.
Kippi Bordowitz (Jan 25 2021 at 19:52):
@Chris Moesel Wow, thanks a million. Just came out of a 5 hour power outage and it's 22:00 so I think I'll wait till tomorrow haha. But once again - I really appreciate it all!
Elliot Silver (Jan 25 2021 at 21:55):
To touch on one thing that was sort of glossed over in the other answers, the _genonce.sh script, etc. are wrappers around the IG publisher. 99% of the time, they provide the correct parameters to the Java publisher with. Most of the rest of the time, you can pass command line arguments to the script to get the specific behaviour you want. It is only in a very small set of cases that you would need to invoke the publisher.jar directly, supplying all the parameters yourself.
Also, if you decide to customize the template, it isn't hard, but it isn't well documented. My best suggestion is to start (here)[https://build.fhir.org/ig/FHIR/ig-guidance/template.html] and look at some of the other examples.
Kippi Bordowitz (Jan 26 2021 at 09:57):
@Elliot Silver thanks!
Kippi Bordowitz (Feb 03 2021 at 20:48):
Ok. New noob question:
I'm using a HAPI server and my partner and I are running into this problem we can't figure out:
I'm trying to understand the purpose of the url field in a ValueSet. I thought it is used as the canonical URL of the ValueSet, the one to which bindings point, for example, but it seems that the server looks at the binded url as an actual resource address.
In profiles on the other hand, the server finds the local StructureDefinition resource by it's url attribute, even if the this url leads to nowhere.
What is behind this defference in bahaviour, and what the value set's url attribute is used for?
Grahame Grieve (Feb 03 2021 at 20:53):
this looks like a question that should be on the #hapi stream
Grahame Grieve (Feb 03 2021 at 20:54):
but your understanding is correct.
Kippi Bordowitz (Feb 04 2021 at 04:07):
@Grahame Grieve thanks.. [slaps forehead] Of course :)
Last updated: Apr 12 2022 at 19:14 UTC