Monthly Archives: February 2016

Question: Locating the #FHIR end-point

Question:

I have been trying to develop FHIR app using your API. The url “http://fhir2.healthintersections.com.au/Patient” doesnt return me list of patients. Am i hitting the right URL?

Answer:

No. and in fact, this trips lots of people over for lots of servers. Very often, the link provided to the server is a reference to a web page that describes the various end-points the server offers, and the security details for them. For instance, my server offers 2 end points – http://fhir2.healthintersections.com.au/open, which anyone can use, and https://fhir2.healthintersections.com.au/closed, which requires authorization via Smart on FHIR.

So the url you’re looking for is http://fhir2.healthintersections.com.au/open/Patient

 

Question: #FHIR conformance requirements

Question:

  • status has a cardinality of 0..1 , but it is mentioned as required under Description.
  • Similarly, rest/resource/searchParam/modifier  has cardinality of 0..* which means optional, but it is mentioned as required under Description.

Should I go by the cardinality of these elements?

Answer:

Conformance Status does have a cardinality of 0..1. None of us know why it’s 0..1 not 1..1 like all the other conformance resources. See gForge task 9581.

But the ‘required’ under description for all of these elements refers to the value set binding – if you have one of these elements, it is required to come from one of the specified codes in the valueset. So, yes, you should go by the stated cardinality.

IEEE Event: Health Informatics on #FHIR

Health Informatics on FHIR: Opportunities in the New Age of Interoperability

A half day, pre-HIMSS Workshop on Saturday February 27th from 9:30 – 12:30 Westin Las Vegas Hotel, Casino & Spa

Organizers: Professors May Wang, PhD Professor (maywang@bme.gatech.edu) and Mark Braunstein, MD Professor of the Practice (mark.braunstein@cc.gatech.edu – Georgia Tech

Keynote: Charles Jaffe, MD, PhD, CEO of HL7: Toward a Global Health Interoperability Standard (30 minutes)

Panel 1: The FHIR Standard (90 minutes – Moderator: Mark Braunstein) + Panel Discussion / Q&A

  • Grahame Grieve, HL7 FHIR Project Leader: Toward Global Interoperability through the FHIR Standard
  • Josh Mandel, MD Lead Architect for the SMART on FHIR project, Harvard Boston Childrens Hospital: FHIR as a Universal App Platform
  • Charles Jaffe: The Argonaut Project

Panel 2: Healthcare in the Age of Interoperability (90 minutes – Moderator: May Wang) + Panel Discussion / Q&A

  • Robert A Greenes, MD, PhD, Professor, Biomedical Informatics, Arizona State University (co-author Aziz Boxwala, MD, PhD, Meliorix Inc, and mWorksHealth, Inc, La Jolla, CA): Enabling Patient-Centered Care by Liberating Data.
  • Jimeng Sun, PhD, Associate Professor, School of Computational Science and Engineering, Georgia Tech: FHIR-based Clinical Decision Support: An Epilepsy Case Study.
  • Paula Braun, MS Data Science Entrepreneur, CDC: FHIR and Public Health: Death Reporting Case Study
  • Gil Alterovitz, PhD, Harvard/MIT Health Sciences and Technology Division Children’s Hospital Informatics Program: SMART on FHIR Genomics

In addition, there will be up to five poster presentations available to the audience.

See IEEE page for  registration

 

Patient Matching on #FHIR Event at HIMSS

In a couple of weeks I’m off to HIMSS at Los Vegas. I’m certainly going to be busy while I’m there (If you’re hoping to talk to me, it would be best to email me to set up a time). Before HIMSS, there’s several satellite events:

  • Saturday: Health Informatics on FHIR: Opportunities in the New Age of Interoperability (IEEE)
  • Sunday: Patient Matching on FHIR event (HIMSS)
  • Monday: First joint meeting between HEART/UMA & FHIR/SMART teams – if you want to attend this meeting, let me know by email (there’s a couple of places still open)

About the Sunday meeting, quoting from the announcement:

Previous work included a Patient Testing Matching Event on this idea was developed at an event in Cleveland, OH on August 14th, 2015 at the HIMSS Innovation Center.  The event covered a tutorial on FHIR along with sessions on patient matching.  A key takeaway from the event was that the healthcare community can advance interoperability by working on a standard Application Programming Interface (API) for master patient index software, commonly used to facilitate patient data matching.

In fulfillment of this vision, we are hosting this second Patient Matching on FHIR Workshop in conjunction with the HIMSS 16 Annual Conference in Las Vegas.  We invite:

─         Algorithm vendors
─         EMR vendors,
─         Developers and standards experts
─         All interested parties

So, here’s passing on the invitation – see you there!

ps. I’ll pass on information about the IEEE event when I get a link.

Possible alternative syntaxes for #FHIR extensions

At the last few HL7 working meetings, the FHIR core team has gathered on Thursday evening for a deep technical session. In Orlando, we talked about various open issues to do with profiling (and then we all went to Howl at the Moon). In Atlanta, we explored alternative syntaxes for extensions, which led to a proposal that we put to a fairly large committee meeting (~50 people), a combined cross-section of FHIR stakeholders in Orlando. That proposal died immediately – it got a very hostile reception, actually. A couple of the participants at the meeting thought that this was a reflection of insider bias, and asked me to present the proposal on my blog so that it gets a wider set of eyes looking at it. So here it is.

Current Situation

Here’s an example resource with several extensions:

<Patient xmlns="http://hl7.org/fhir">
 <id value="patient-example"/>
 <extension url="http://hl7.org/fhir/StructureDefinition/us-core-race">
   <valueCodeableConcept>
     <coding>
       <system value="http://hl7.org/fhir/v3/Race"/>
       <code value="2106-3"/>
     </coding>
   </valueCodeableConcept>
 </extension>
 <extension url="http://hl7.org/fhir/StructureDefinition/us-core-ethnicity">
   <valueCodeableConcept>
     <coding>
       <system value="http://hl7.org/fhir/v3/Ethnicity"/>
       <code value="2135-2"/>
     </coding>
   </valueCodeableConcept>
 </extension>
 <extension url="http://hl7.org/fhir/StructureDefinition/patient-clinicalTrial">
   <extension url="clinicalTrialNCT">
     <valueString value="NCT01647425"/>
   </extension>
   <extension url="clinicalTrialPeriod">
     <valuePeriod>
       <start value="2012-04-01"/>
       <end value="2013-09-30"/>
     </valuePeriod>
   </extension>
   <extension url="clinicalTrialReason">
     <valueCodeableConcept>
       <coding>
         <system value="http://snomed.info/sct"/>
         <code value="254637007"/>
         <display value="NSCLC - Non-small cell lung cancer"/>
       </coding>
     </valueCodeableConcept>
   </extension>
 </extension>
 <extension url="http://hl7.org/fhir/StructureDefinition/patient-birthTime">
   <valueDateTime value="2012-06-07T06:12:45-05:00"/>
 </extension>

This is taken from one of the standard DAF examples, and excludes all the normal patient content (not related to this discussion). We – the core team – are not considering changing how extensions work, only how they are represented. Fundamentally, an extension is a pair: a URL to references a definition, and a value. But actually, on the wire, extensions are a triple: the URL, the value, and the type, so that parsers know how to parse the value without having to find the definition of the extension (and so that extensions can allow a choice of type for the value).

What we wanted to know was whether we could find a better syntax to represent extensions. What’s wrong with the current form? Well, feedback from implementers is consistent: the existing form is verbose, and the identity of the extension – the URL – is in an attribute, which is a step away from where you’d like it to be – in the element name.

Aside: it’s exactly the same issue in JSON as XML. And this blog entry will exclusively show XML, not JSON. That’s not because we don’t care about JSON – we do, greatly – but because as far as we are aware, the JSON issues are the same as XML, minus namespaces (yay!). So other than the namespace hacking option below, the same argument applies to JSON.

Prelude: XML Schema

The current approach to extensions is certainly the optimal approach to extensions if you want to use XML schema to describe the general wire format. As long as we want to support schema so that you can generate working code from the schema, then there’s no discussion to be had – we’re going to be sticking with the current extension format (at least in XML).  This whole discussion presumes that we might change that if there was compelling advantage from dropping it. And if there is an advantage, it would be here.

Option #1

So the first option we considered looked like this:

<Patient xmlns="http://hl7.org/fhir" definition="http://...qicore-patient">
 <id value="patient-example"/>
 <us-core-race>
   <coding>
     <system value="http://hl7.org/fhir/v3/Race"/>
     <code value="2106-3"/>
   </coding>
 </us-core-race>
 <us-core-ethnicity>
   <coding>
     <system value="http://hl7.org/fhir/v3/Ethnicity"/>
     <code value="2135-2"/>
   </coding>
 </us-core-ethnicity>
 <clinicalTrial>
   <NCT value="NCT01647425"/>
   <clinicalTrialPeriod>
       <start value="2012-04-01"/>
       <end value="2013-09-30"/>
   </clinicalTrialPeriod>
   <clinicalTrialReason>
     <coding>
       <system value="http://snomed.info/sct"/>
       <code value="254637007"/>
       <display value="NSCLC - Non-small cell lung cancer"/>
     </coding>
   </clinicalTrialReason>
 </clinicalTrial>

In this scheme, an applicable profile is declared on the root. The profile defines the wire format names for the extensions. In order to parse this, a parser needs to access the definition so it can parse the content. There’s several problems with this approach:

  • if you can’t get the definition, you can’t parse the (unknown) content
    • This can be an issue of networks, but also time. (E.g. Looking at a record 20 years later). It would essentially force systems to store the definition with the data
  • you have to pick one definition – one profile, and fall back to the old extension syntax for extensions defined in other profiles (and mixing profiles is a common thing to do)
  • if you do this, it’s basically a ‘local syntax’, and you have to have perimeter exchange methods, or use a reference implementation to read the content. The practical ramifications of this are less than ideal

Note: The idea of perimeter exchange methods comes from the idea that a group of implementers could form their own private club, and use FHIR just among themselves. In this scheme, they can assume that they know each other’s secrets, and take all sorts of short cuts. But as soon as resources leak outside their little club (as will almost certainly happen), the secrets won’t be known. Hence, on the perimeter of the club, the secrets have to be unwound. In this case, the secret is the ‘known’ definition profile.

In effect, then, this would be a local optimization of FHIR – green FHIR, if you want. That’s fine, but that’s not the solution we’re looking for.

Option #2:

<Patient xmlns="http://hl7.org/fhir">
 <id value="patient-example"/>
 <us-core-race xmlns="http://hl7.org/fhir/StructureDefinition/">
   <valueCodeableConcept>
     <coding>
       <system value="http://hl7.org/fhir/v3/Race"/>
       <code value="2106-3"/>
     </coding>
   </valueCodeableConcept>
 </us-core-race>

This option misuses the namespace technique in xml to inline the extension name (for JSON, you’d just inline the name by itself). We didn’t seriously talk about this for very long. The biggest problem is that names are variable because there’s no imposed uniqueness on them. Unless you ban using name clashes (which we have no ability to do, and we wouldn’t have any structure that we could use to prevent implementers getting caught between two uses of the same name, the names have to change depending on the local context. This is also the form that json implementers didn’t like (and, btw, there’s no way to deal with modifiers). This option just wasn’t a good idea. Namespaces aren’t the problem, and they’re not the solution either.

Option #3:

<Patient xmlns="http://hl7.org/fhir">
 <schema>
   <item name="us-core-race" 
     url="http://hl7.org/fhir/StructureDefinition/us-core-race" type="CodeableConcept"/>
   <item name="clinicalTrial" 
     url="http://hl7.org/fhir/StructureDefinition/patient-clinicalTrial">
     <item name="clinicalTrialNCT" 
       url="clinicalTrialNCT" type="string">
     <item name="clinicalTrialPeriod" 
       url="clinicalTrialNCT" type="Period">
     <item name="patient-clinicalTrialReason" 
       url="clinicalTrialNCT" type="CodeableConcept">
   </item>  
 </schema>
 
 <us-core-race>
   <valueCodeableConcept>
     <coding>
       <system value="http://hl7.org/fhir/v3/Race"/>
       <code value="2106-3"/>
     </coding>
   </valueCodeableConcept>
 </us-core-race>
 <clinicalTrial>
   <clinicalTrialNCT value="NCT01647425"/>
   <clinicalTrialPeriod>
       <start value="2012-04-01"/>
       <end value="2013-09-30"/>
   </clinicalTrialPeriod>
   <clinicalTrialReason>
     <coding>
       <system value="http://snomed.info/sct"/>
       <code value="254637007"/>
       <display value="NSCLC - Non-small cell lung cancer"/>
     </coding>
   </clinicalTrialReason>
 </clinicalTrial>

This form starts with a manifest that declares the names, types, and urls for all the extensions. Then you just use the name on the wire.

The ramification of this is that you have to iterate the content twice when you write, so the schema can be complete upfront – and the names are still variable too. It’s also really hard to build with xslt or equivalent – you need serious logic to build the schema on the fly. This would impose that serious logic on anyone writing resources that included extensions. Also, if you were migrating content from one resource to another, you’d have to track the manifest, and potentially rename everything. And you could never use stable names for extensions in your code- you’d still end up accessing extensions by their URLs

Summary:

Well, by the time we got here, we were a bit glum. We hadn’t come up with any thing that was remotely a candidate alternative. None of these approaches represents a net benefit of the current approach – while they look good (or, at least, the extensions look better), the practical ramifications for readers and writers are unhappy.

Final option:

The final option we considered was radically different to the others. Here’s what it looks like:

<Patient xmlns="http://hl7.org/fhir">
 <id value="patient-example"/>
 <birthTime value="2012-06-07T06:12:45-05:00"/>
 <active value="true"/>
 <name>
   <use value="official"/>
   <family value="Lerr"/>
   <given value="Todd"/>
   <given value="G."/>
   <suffix value="Jr"/>
 </name>
 <telecom>
   <system value="phone"/>
   <value value="(555) 555 1212"/>
   <use value="work"/>
 </telecom>
 <telecom>
   <system value="email"/>
   <value value="person@example.org"/>
   <use value="work"/>
 </telecom>
 <gender value="male"/>
 <birthDate value="2012-06-07"/>
 <deceased type="boolean" value="false"/>
 <address>
   <use value="home"/>
   <line value="123 North 102nd Street"/>
   <line value="Apt 4d"/>
   <city value="Harrisburg"/>
   <state value="PA"/>
   <postalCode value="17102"/>
   <country value="USA"/>
 </address>
 <us-core-race type="CodeableConcept" list="true">
   <coding>
     <system value="http://hl7.org/fhir/v3/Race"/>
     <code value="2106-3"/>
   </coding>
 </us-core-race>
 <us-core-ethnicity type="CodeableConcept">
   <coding>
     <system value="http://hl7.org/fhir/v3/Ethnicity"/>
     <code value="2135-2"/>
   </coding>
 </us-core-ethnicity>
 <clinicalTrial>
   <clinicalTrial.NCT type="string" value="NCT01647425"/>
   <clinicalTrial.period type="Period">
     <start value="2012-04-01"/>
     <end value="2013-09-30"/>
   </clinicalTrial.period>
   <clinicalTrial.reason type="CodeableConcept">
     <coding>
       <system value="http://snomed.info/sct"/>
       <code value="254637007"/>
       <display value="NSCLC - Non-small cell lung cancer"/>
     </coding>
   </clinicalTrial.reason>
 </clinicalTrial>
</Patient>

You can tell that we liked this enough to consider it seriously because we went ahead and filled out the rest of the resource.

Note that there a second thing going on in this resource: we changed the way that choice types work. Instead of using value[x], and appending the type name to the element, we used a type attribute (of course, in practice, in spite of the difficulties it presents, if we actually did this, we’d use xsi:type in the XML. In JSON, you’d have a property named “type” or “dataType”. This is a basically separate notion, but is required to eliminate the “value” element.

This is a very nice representation for extensions. Sweet. But in order to make this work – e.g. to avoid name clashes – we would need a global registry that contained a list of wire format names, along with, for each name, the following information:

  • name – the name in the instance
  • url – the canonical url for the extension
  • modifier – whether this is a modifier
  • list – whether this is repeats or not
  • type[] – what types this name can be
  • path[] – where the name can appear
    • children[]
    • name
    • type
    • list
      • children[] (etc)

And this global registry would need to be very carefully curated so that the names are useful, and remain useful as it grows. That’s a tough challenge.

Implementations would take one of two approaches to reading the instances:

  • download a snapshot of the global registry occasionally, and use that snapshot when reading and writing resources (e.g. the reference implementations would do this)
  • download a snapshot of the global registry at design time, and generate schema / code / something etc for whatever tool/code reads and writes the resources

So, if we established such a registry, and made general purpose implementations (the ones that have to deal with multiple profiles) more complicated, we’d have simpler instances, and it would be easier for single purpose applications. Is that worth it? Well, that’s the question we put to the combined committee group at Orlando. Nearly everyone in the group – except for a small but keen minority – was strongly against this option, for the following reasons:

  • it complicates general purpose applications
  • Although most individuals start with single purpose applications, most will quickly migrate to multi-purpose applications (or even to general purpose applications)
  • Implementers like having a single general purpose schema.
  • Running the registry well – particularly with a good SLA on turn around – would be onerous and expensive

ok. So perhaps that group over-represented the general implementers, and didn’t represent the single-purpose implementers – though the room was weighted towards vendors and consultants who support single-purpose implementers extensively, so it possibly wasn’t as unbalanced as it first looked. So here’s a write up of the discussion so that participants not in the room can consider and have their say.

p.s. My own opinion is that I’d much prefer not to have the registry, since running it would be my concern. And it doesn’t sound like fun. Actually updating the reference implementations to use the global registry would be straight forward, but it does introduce a step to manage – downloading the latest definitions. I think it would be hardest for server authors who don’t use the reference implementations – sufficiently hard that I wonder whether it would become infeasible to write servers without the reference implementations. So in the end, my personal preference is to keep things as they are.

 

Example Batch Requests for Patient Summary (#FHIR)

Andy G from Mitre submitted this gForge task:

It is currently difficult for a FHIR client to create a summary display for a patient. For example, if a application wanted to display demographic information, encounters, vital signs and a problem list, medication list and allergies, it has the following choices:

1) It could make multiple requests to the FHIR server. It could request the Patient resource and then make repeated FHIR search requests against all of the different resource types it needs.

2) It could use the $everything operation. This will likely return more information than what is needed. Yes, it can be filtered by time, but more likely, the desire is to filter by data type.

3) It could perform a search on the Patient resource and use _revinclude to pull in additional resources. There appears to be no capability to filter the reverse included resources, which will almost certainly return more information than desired. In the pervious example, a client looking for vital signs would reverse include Observations. This could create a flood of information.

I would suggest modifying the $everything operation, or creating a new operation that allows for more advanced filtering of what is returned. One suggestion would be to add a resource parameter to the $everything operation. That, in conjunction with the time bounds would go a long way towards solving this issue.

Indeed, that’s an interesting problem. After discussion, we found that a batch operation was the best outcome, so Andy kindly contributed a couple of examples:

  • meds_and_allergies – Retrieve a patients medications, allergies, problems and immunizations (e.g. the Australian PCEHR shared health summary)
  • simple_summary – Retrieve a patient’s conditions, medication statements and blood pressure readings since a given date

And to help, I’ve attached my server’s response, based on the examples in the specification:

We plan to add these examples to the specification in the future.

 

Question: #FHIR Common Search Parameters

Question:

I am working on fhir based rest server. I have already implemented create, delete, read, update, and history services. I am working on search service and i have some difficulties to understand what exactly do parameters mean especially common parameters. For example _text,_content,_list,_query. Can you give me more specified examples please?

Answer:

_text:

GET [base]/Condition?_text=(bone OR liver) and metastases

This example from the specification shows how you could search the xhtml content of the narrative for the word ‘metastases’ and either ‘bone’ or ‘liver’. The expectation is that your server will pass the narrative to an indexing engine (typically, either Lucene, Solr, or Microsoft SQL Text Indexer) and that when a search specifies the _text parameter, the parameter value will be passed to the search engine as is. The trick is integrating the search engine with the other search parameters, but solving that is out of scope for my blog.

_content:

This is nearly the same as the _text resource, except instead of the narrative, it searches the entire text of the resource – that is, the xhtml and all the primitive values. You have to assemble this yourself somehow and pass it to the search engine. I don’t think many implementers have done this one.

_list:

This is a short cut to allow you to search for resources that are in some list. There’s 2 main use cases for this – when a list is being used to track an ad-hoc selection of resources, such as a clinically interesting patient list, the _list parameter lets you search through only the items in that list. The other use is for EHRs or other clinical systems that maintain ‘current lists’, such as ‘current medication list’ or ‘current problem list’ – a way to search those current lists only.

_query:

This is for when the server wants to define it’s own search that works differently to the normal search. If the server sees a _query parameter, it cannot ignore it, since the parameters may not have the normal meaning. When a server defines it’s own kind of query, it can use the rest of the parameters however it wants. The FHIR specification defines one of these, for MPI Search

Right-To-Left scripts in #FHIR

Today, I’m at Linux Conference Australia. I watched a hysterically funny and very interesting presentation by Moriel Schottlender on using Right-To-Left scripts, such as Hebrew, Arabic, Farsi, etc:

browsers have problems when deciding what to do when languages are mixed up, and that, my friends, is a recipe for really weird issues when typing and viewing bidirectional text.

Check the full presentation. And yes, Moriel showed us some really confusing stuff. She kept showing images like this:

This, btw, is your mind trying to process RTL issues (and how could I not post that image?). Moriel has a web site demonstrating some of this stuff (including the piece de resistance, an animated bmp).

Anyway, after the presentation, I asked Moriel whether she had any thoughts about RTL use in a RESTful interface (say, maybe, FHIR). She didn’t have any strong experience, but a combination of her presentation, and her comments after, led to the following advice:

  • If you’re using RTL script entirely, that should be pretty straight forward. The framework of a resource is all LTR ASCII, but the contents of the string primitives are RTL. That works fine
  • The tricky bit is where you mix scripts – e.g. an Arabic word mixed in with an english sentence

Actually, that’s not at all an unusual idea. You can see an example of this here on Wikipedia. And in a clinical environment, it would be a typical thing to happen in somewhere like Saudi Arabia, with a lot of foreigners working in the healthcare system, and mixing English and Arabic. You can watch Moriel’s presentations for fun with left, right, parentheses etc, and see how tricky that could be. Anyway, the basic advice is:

Anywhere you mix LTR and RTL scripts, make sure you use Unicode control characters to mark the edges of the direction changes.

And one more conclusion I drew:

  • There’s little prospect we’ll ever publish an IG that makes sensible use of RTL content

If anyone has experimented with RTL content in FHIR – I’d love to hear about it: we want to support that properly.

p.s. I’m here at LinuxConf to talk about the FHIR community as an open source project.

Question: #FHIR _format parameter

Question:

The FHIR specification says:

Servers SHOULD support the optional _format parameter to specify alternative response formats by their MIME-types. This parameter allows a client to override the accept header value when it is unable to set it correctly due to internal limitations.

If both _format and accept headers are present with valid but different values, which of them should take the precedence?

Answer:

_format is definitely an override, and always takes precedence if it’s present. It’s explicitly provided for where the user doesn’t have access to the Accept: header, but needs to specify what type to return. Typically, this is a user using a browser manually, or an XSLT web call, though I’ve heard of a few other cases.