Fixed code sets in FHIR

One of the common use cases for FHIR is going to be to create a ‘proxy’ or ‘façade’ FHIR server that provides a FHIR interface against an existing data source – and this is what we are doing at Orion Health in front of our Patient Administration System. (We’re actually building a rather cool mobile medication administration app – hope I’m allowed to say that!).

One of the issues we’ve come across is where there is a property with datatype of code and a fixed set of code values (a codeset) – such as  MedicationPrescription.status.

The problem we are facing is that in the ‘back end’ system, this field is a configurable set of values – and it often won’t match the values defined in FHIR. This is bad enough for optional properties, but even worse when the property is a required one – such as MedicationAdministration.status.

Now there are very good reasons why the workgroup that designed these resources have made the codes a fixed set – they are important properties that a recipient must understand to safely use the resource – and we are about interoperability after all. But it’s still a problem we need to solve.

I can think of a few possibilities for us.

 Option 1 is to change the codeset in the backend system to that defined in the FHIR resource – perhaps a bit unlikely…

 Option 2. Ideally, every value in the back end system can be mapped to one of the values from the fixed code set – with an acceptable loss of fidelity. Then, you can create an extension to hold the original value. In this way a recipient who doesn’t understand your custom codeset can still safely process the resource (using the defined property) but internal clients can apply whatever extra logic is supported by the enhanced set in the extension.

For example, the MedicationPrescription resource has a status property of which one of the values is ‘on-hold’. If the backend system has a number of values that could mean this (on-hold due to an operation, on-hold due to other therapy, on-hold because the pharmacy has run out) then you can set the status value to on-hold, and the extension can contain the more precise value. Incidentally, this might be one of the few places where a Coding datatype is appropriate.

 Option 3. If you have values that simply cannot be mapped in this way then you can use a modifierExtension on the property itself to carry the extra value. This severely reduces the interoperability of your resource of course, as a recipient must be able to understand and process your custom value – and should reject the resource if it cannot.

(It may not have been obvious that resource properties can have extensions as well as the resource themselves – check out the spec for more details. In fact, it’s possible to extend a datatype if you need to!)

If you do find yourself in this position, it would pay to ask a question through one of the various FHIR support channels – you might get advice about a value you can use, or if your use case is compelling enough the codeset can be extended in FHIR itself.

 So there you go. A price of being interoperable is that you have to conform to a set of agreed behavior and content – and sometimes that means compromise. Hopefully there will always be some way to achieve the business requirements, and especially in this DSTU phase of FHIR changes to the spec are quite possible – if there is a good enough reason.

Modelling Encounters in FHIR: Part 2

I was having a chat with some colleagues in New Zealand (who shall remain nameless, but you know who you are PJ & KA) about Encounters – specifically how to model an encounter (using openEHR archetypes as it happens), and it became evident that we were talking about slightly different things by the word ‘encounter’. I was referring to the FHIR encounter – a resource that has mainly administrative information about a contact with a patient (date, time, participants and so on), but my colleagues were referring to the more holistic concept of encounter – including all the clinical information collected during that encounter, actions performed, and so on.

So that we were talking about the same thing, I volunteered to write down how you could express these concepts in FHIR – so here it is. A simple Primary Care (Ambulatory Care in the US) consultation, which has a clinical note (subjective and objective) plus a prescription.

primary care observation

Note that I’ve used a Composition resource to establish the context of the Consultation note. This is a versatile resource (as most of them are in truth), which is also used in a FHIR document, although it doesn’t have to be – as this example shows.

The composition references the encounter, and also – through the sections of the composition – the clinical findings and actions that occurred during the consultation. There is some duplication of data – eg dates are in both encounter and composition – but nothing to get too concerned about.

This is how you could store the record in a data store, and of course it’s really easy to serialize into a FHIR document if you want to send a copy of the record to someone else – it would be an atom feed with 7 entries/resources in it with the appropriate references (see an example of a similar FHIR document here). Of course, you would also need to include copies of the referenced resources like Patient and Practitioner (that I left off the picture for simplicity) that would increase the resource count slightly.

Interestingly, this layout is very similar to how a CDA document would be represented – with the Composition (plus Patient and Practitioner) as the CDA header, and the Encounter, Clinical Findings and Medications Prescribed as sections. Co-incidence? I think not…

So: in our modelling work we really need to model the Encounter as a separate Entity with references to the clinical parts of the consultation, rather than a single model that seeks to encompass the whole thing (IMHO).

Modelling Encounters with FHIR

One of the tasks I’ve been given here at Orion is to look at our internal data stores, and see how we could create a FHIR based service layer that would allow external (and internal) consumers to interact with that store.

I started with the Encounter service, and things went pretty well – but I realized that if this was to make sense to other BA’s (Business Analysts) and Developers then I needed to draw the bigger picture – how the resources would relate to each other when representing an encounter – it’s not quite as simple as it might seem!

The biggest change in thinking is going to be thinking in terms of multiple resources. If we want to retrieve the details of a single encounter, then we’re not going to just call the service and get back a single object that represents the encounter and all the properties of that encounter – rather we’re going to get back an ‘object graph’ – a number of resources related to that encounter contained within an atom bundle.

The client could request that the server return the referenced resources by using the _include parameter to specify the resources that it would like to be included in the returned bundle. (It could also get back just the Encounter and then make separate calls for all the referenced resources – but that’s a bit klutzy, and there are other problems that we’ll talk about in a minute).

I’ve used the New Zealand situation for this discussion to demonstrate the process I used: the actual relationship of entities will be different in different realms of course (HL7 uses the term ‘realm’ to refer to different countries).

OrgLoc

So, from the diagram we can see that:

  • The hospital organization is part of a DHB (District Health Board)
  • A primary care centre is in the catchment area of a hospital (this needed an extension).
  • The hospital location has a number of ward locations
  • An encounter at a hospital refers to the hospital Organization as the service provider, and has relationships within a number of wards within that hospital. It also has relationships with the patient and one or more participants
  • A primary care encounter has exactly the same sort of relationships  – albeit with different resource instances. (Just for fun, I associated the Primary Care Clinician with the hospital encounter to show that the GP was also involved in the patients care while in hospital. This is not uncommon in New Zealand – or at least it was when I practiced medicine a few decades ago…)

So what does this look like on the wire?

Well the snippet below shows a hospital encounter, with the resources within a bundle and appropriate  references between resources for the (It’s not complete of course – in fact there’s just enough in there to allow it to validate).

<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Encounter Resource with all related Resources as separate resources</title>
    <id>urn:uuid:500bee81-d973-4afe-b592-d39fe71e38</id>
    <updated>2013-05-28T22:12:21Z</updated>     <!-- Time the bundle was built -->
    <!-- Author is required by the Atom spec. FHIR doesn't use it-->
    <author>
        <name>Harold House Surgeon</name>
    </author>

    <entry>
        <title>Encounter Resource</title>
        <id>cid:encounter1</id>
        <updated>2013-05-28T22:12:21Z</updated>
        <content type="text/xml">
            <Encounter xmlns="http://hl7.org/fhir">
                <text>
                    <status value="additional"/>
                    <div xmlns="http://www.w3.org/1999/xhtml">An encounter at Ward 10 Middlemore hospital,
                    for John Cardinal from 1st to 3rd January 2014. Dr Marcus Welby attending.</div>
                </text>
                <status value="finished"/>
                <class value="inpatient"/>
                <subject>
                    <reference value="cid:patient"/>
                    <display value="John Cardinal"/>
                </subject>
                <participant>
                    <individual>
                        <reference value="cid:doctor"/>
                        <display value="Dr Marcus Welby"/>
                    </individual>
                </participant>
                <period>
                    <start value="2014-01-01"/>
                    <end value="2014-01-03"/>
                </period>
                <location>
                    <location>
                        <reference value="cid:ward"/>
                        <display value="Ward 10"/>
                    </location>
                    <period>
                        <start value="2014-01-01"/>
                        <end value="2014-01-03"/>
                    </period>
                </location>
                <serviceProvider>
                    <reference value="cid:hospital"/>
                </serviceProvider>
            </Encounter>
        </content>
    </entry>

    <entry>
        <title>Patient details</title>
        <id>cid:patient</id>
        <updated>2013-05-28T22:12:21Z</updated>

        <content type="text/xml">
            <Patient xmlns="http://hl7.org/fhir">
                <text>
                    <status value="additional"/>
                    <div xmlns="http://www.w3.org/1999/xhtml">John Cardinal</div>
                </text>
            </Patient>
        </content>
    </entry>

    <entry>
        <title>Hospital</title>
        <id>cid:hospital</id>
        <updated>2013-05-28T22:12:21Z</updated>

        <content type="text/xml">
            <Organization xmlns="http://hl7.org/fhir">
                <text>
                    <status value="additional"/>
                    <div xmlns="http://www.w3.org/1999/xhtml">Middlemore Hospital</div>
                </text>
            </Organization>
        </content>
    </entry>

    <entry>
        <title>Location (ward)</title>
        <id>cid:ward</id>
        <updated>2013-05-28T22:12:21Z</updated>

        <content type="text/xml">
            <Location xmlns="http://hl7.org/fhir">
                <text>
                    <status value="additional"/>
                    <div xmlns="http://www.w3.org/1999/xhtml">Ward 10</div>
                </text>
            </Location>
        </content>
    </entry>

    <entry>
        <title>Practitioner</title>
        <id>cid:doctor</id>
        <updated>2013-05-28T22:12:21Z</updated>

        <content type="text/xml">
            <Practitioner xmlns="http://hl7.org/fhir">
                <text>
                    <status value="additional"/>
                    <div xmlns="http://www.w3.org/1999/xhtml">Dr Marcus Welby</div>
                </text>
            </Practitioner>
        </content>
    </entry>

</feed>

The query that would retrieve this bundle looks something like this:

GET [root]/Encounter?subject={patientID}&_include=Encounter.subject&_include=Encounter.Location...

Now there’s actually an issue with this representation, and it relates to our old friend the resource identity.

In this bundle all the resources are identified as ‘cid:’ references – meaning that they don’t refer to ‘real’ resources back on the server. (Because our back end is not fully FHIR enabled (yet), we’ve constructed the resources ‘on the fly’ from the data in the Encounter when the query was processed).

But what should the recipient do with the bundle if it wanted to save it locally? It would need to create a new resource locally for each one in the bundle. What would happen if the client made 2 separate queries for encounters, and each encounter referred to the same patient? The client would have no way of knowing this, and so would create another resource for the same patient.

So the more correct way to deal with this is to ‘contain’ the unidentified resources within the Encounter like this:

<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Encounter Resource with all related Resources as contained resources</title>
    <id>urn:uuid:500bee81-d973-4afe-b592-d39fe71e38</id>
    <updated>2013-05-28T22:12:21Z</updated>     <!-- Time the bundle was built -->
    <entry>
        <title>Encounter Resource</title>
        <id>cid:enc1</id>
        <updated>2013-05-28T22:12:21Z</updated>
        <content type="text/xml">
            <Encounter xmlns="http://hl7.org/fhir">
                <text>
                    <status value="generated"/>
                    <div xmlns="http://www.w3.org/1999/xhtml">An encounter at Ward 10 Middlemore hospital,
                        for John Cardinal from 1st to 3rd January 2014. Dr Marcus Welby attending.</div>
                </text>
                <contained>
                    <Patient id="patient">
                        <name>
                            <text value="John Cardinal"/>
                        </name>
                    </Patient>
                </contained>
                <contained>
                    <Practitioner id="doctor">
                        <name>
                            <text value="Dr Marcus Welby"/>
                        </name>
                    </Practitioner>
                </contained>
                <contained>
                    <Location id="ward">
                        <name value="Ward 10"/>
                    </Location>
                </contained>
                <contained>
                    <Organization id="hospital">
                        <name value="Middlemore Hospital"/>
                    </Organization>
                </contained>
                <status value="finished"/>
                <class value="inpatient"/>
                <subject>
                    <reference value="#patient"/>
                    <display value="John Cardinal"/>
                </subject>
                <participant>
                    <individual>
                        <reference value="#doctor"/>
                        <display value="Dr Marcus Welby"/>
                    </individual>
                </participant>
                <period>
                    <start value="2014-01-01"/>
                    <end value="2014-01-03"/>
                </period>
                <location>
                    <location>
                        <reference value="#ward"/>
                        <display value="Ward 10"/>
                    </location>
                    <period>
                        <start value="2014-01-01"/>
                        <end value="2014-01-03"/>
                    </period>
                </location>
                <serviceProvider>
                    <reference value="#hospital"/>
                    <display value="Middlemore Hospital"/>
                </serviceProvider>
            </Encounter>
        </content>
    </entry>

</feed>

This makes it explicit to the recipient that the contained resources only have meaning within the context of the containing Encounter. (And note that the contained resources no longer have a <text> element – the spec discourages this).

As we progress with FHIR, we’ll be able to start to expose ‘real’ resources (with proper identities). For example, once we have a Patient resource endpoint available, then we won’t have to contain the Patient resource in the Encounter – it will be an ‘identifiable’ resource with a ‘real’ URL that points to it – and we can choose to include the resource in the bundle or not. This does mean that the representation will change over time with resources moving from being contained to being ‘real’ resources in their own right, but that’s something that comes with being a FHIR client.

Of course this interface is actually more complex than the one it replaced, and it will take more work server-side to produce it that the previous custom version did. Where there was a single ‘object’ representing the encounter, we now have an object graph. But – and it is an important but – our interface can be used by any FHIR compliant system, which means that we can support – and promote – an international ecosystem of health information exchange.

Further, much of the complexity can be hidden behind libraries that are freely available (or we can write our own if we want to). It’s clean and easy to understand. And, finally, we have a design than has been created by some of the smartest minds in healthcare IT – and it didn’t cost us anything!

What’s not to like?

FHIR Videos

Rene Spronk has been active with his video at most of the FHIR connectathons, and has uploaded the videos here. There are also a number of interviews with various people involved in this work. Well worth a look!

These two didn’t seem to be in the list when I reviewed it – but may be there now…

FHIR Elevator Pitch for software developers – by Lloyd McKenzie,
https://vimeo.com/84767819
FHIR approved as a DSTU – comments by Lloyd McKenzie and Ewout Kramer,
https://vimeo.com/84767555

FHIR: A question of identity

One thing that comes up frequently for people new to FHIR is the concept of a resource identity – and I have a great deal of sympathy with this as I also had a lot of trouble getting my head around exactly what this is.

The identity of a resource is one of the fundamental concepts in REST – and in FHIR. In fact the way that you refer to a resource is via its URI – the Uniform Resource Identifier. It is a way of unambiguously locating or specifying the resource: if you have the URI then you can find and refer to it – for example being able to state unambiguously to which patient a particular condition refers.

What seems to trip people up in healthcare is the similar business concept of a patient identifier, like a Medical Record Number (MRN) or in New Zealand the National Health Identifier (NHI) and which is often called a patient ID. Despite the similar sounding (identical!) names, they are quite different.

  • The resource ID refers to the location of a resource (any resource) on a particular server (or at least the ‘external address’ – it’s up to the server where and how  it’s physically stored, but it does agree to always refer to that resource from that place). Further, the resource ID is unique only on that server – it’s not transportable between servers.
  • The MRN is actually an identifier from a registry/system of some sort – and identifies the person/patient for the business purpose of healthcare delivery. In healthcare, this functionality is often supplied by a ‘Master Patient Index’ (MPI) that has all sorts of sophisticated algorithms to help to resolve issues like two identifiers referring to the same person.

So FHIR also has these 2 concepts:

  • The resource ID (specific to a server) that every resource MUST have. If a copy of the same ‘thing’ is stored on different servers, then they will have different IDs, but the ID  will never change on a given server. It’s kind of like a primary key in a database – except that the primary key will change if a record is migrated to another database, which means that the location on that server would change, which means that it is no longer the same resource. A sequential counter or GUID that doesn’t change and stays with the record might be a better choice. The resource ID is not a property of the resource – it is held outside of it.
  • A specific resource (like Patient) CAN have one or more identifier properties that refer to some external system or registry. FHIR doesn’t have any particular requirements of an identifier, only that you can specify the ‘system’ within which the identifier is unique – eg a passport, or a drivers license are equally valid identifiers. And, an identifier can change for a given resource.

Another way to think of the difference is that the resource ID is a ‘system’ level ID – it locates resources and allows one resource to reference another. Change the ID and it becomes a different resource. An identifier is about how humans categorize things – including other humans – and can change.

When a resource is copied from one server to another (maybe it is in a bundle, and the recipient server wants its own copy), then it will receive a new ID on the new server and so is a different resource (there is a different URI that refers to it). However, if there is an identifier property on the resource, then that will remain the same so a consumer of the resources will know that they are actually pointing to the same real world entity – eg a patient.

There is more discussion on resource identity in the spec here, and about the identifier here. And I’ve talked before in this blog about REST in general, and using the ID to manipulate resources.

In this blog I try to consistently refer to a resource ID as its ‘ID’, and a specific identifier property as ‘identifier’

Makes sense?

FHIR: to DSTU or not DSTU, that is the question

When I started this blog, my motivation was two fold: I wanted to continue to learn more about FHIR, and I wanted to capture all the great information that was being captured in the various channels – skype conversations and the HL7 list in particular. In other words a very ‘technical’ blog that could act as an information resource for those new to FHIR. I definitely didn’t intend to comment on the ‘process’ aspects of the standard (those who know me know that I’m not good at that stuff).

I’ve been privileged to be a member of the FHIR Management Group, and our intention for some time has been for the standard to be DSTU (Draft Standard for Trial Use) in January this year (we originally aimed for last September, but that was just too soon) – and from an HL7 procedural perspective we are ready.

However, there have been a number of blog posts in the last couple of days commenting on whether FHIR is actually ready for DSTU now, or whether another ballot round is needed. If you’ve not seen them, then here are the links:  Keith Boone (aka motorcycle guy) and John Moehrke (Security Guru).  Lloyd McKenzie (FHIR expert) has presented the case for the defence.

Now no-one is questioning of the value of FHIR as an upcoming standard – all agree that it is the right way forward – just the actual readiness for DSTU now.

I’ve come to FHIR from the perspective of an implementer – and what attracted me to FHIR was not just the elegance of the approach, but also that it would be available to me soon – I have interoperability issues I need to resolve now. I accept the risks of a draft standard – it WILL change (not MAY change) before it’s a done deal.

But that’s going to be the case anyway – even if there is another round of balloting before DSTU.

And after DSTU then there will be other ballot rounds, and changes WILL continue to occur before normative (where it is fixed) – that’s the consequence of using a standard early on in the development cycle. (The benefits include the value you gain from the work of others, and the ability to affect the development of the standard before it becomes fixed).

And if these risks are too great, then you need to wait for normative in a couple of years, and use something else in the mean time – whatever that may be – and make any changes then.

Whether we go DSTU now or in another 4 months, change is inevitable. So the question for me is: Is FHIR useable for my needs now?

And, for me anyway, it is.

Cheers…

FHIR query syntax: Note to self…

Just a short post to point out a ‘quirk’ in the FHIR syntax for querying so I can look it up again when I forget. (actually, it’s not really a quirk at all – it’s perfectly reasonable, though can be confusing).

It all came about when Josh pointed out an error in my post on retrieving documentReference resources from an server.

We were discussing how you could retrieve a filtered list of documentReference resources for a patient over a period of time, and used the example:

GET  http://registryserver/DocumentReference?subject=100&period >=2013-01-01

However, as Josh pointed out – and as the spec indicates, you need an ‘=’ symbol in there to bind the HTTP parameter ‘period‘ to the value ‘>= 2013-01-01‘ which is what the FHIR server is going to query on. Thus the correct syntax is:

GET  http://registryserver/DocumentReference?subject=100&period= >=2013-01-01

Now, if I had only tested the query out on one of the reference servers before I posted it, I would have avoided the error, but there you go…