Montreal Connectathon

I would imagine that most readers of this blog are aware of the Connectathons that we hold at the beginning of each Working Group Meeting. These events are critical to the evolution of FHIR as an ‘implementer friendly’ standard, so we love to have as many people present as possible!

Read more of this post

The clinFHIR Chat

One of the things we’ve found at the various connectathons we’ve held is that communication between the attendees can be an issue – there are quite a number of different ‘streams’ of activity and it can be hard to connect people with questions or comments, to people with answers.

We’ve used skype in the past, which has been OK, but has a number of limitations – it can be quite a firehose, which means that stuff is missed, there’s no easy to maintain a ‘thread’ of conversation (though sometimes interesting when threads get mixed together!) and hard to review the history at the end of the event. Oh – and there’s a fixed limit of 300 people per conversation, which we recently discovered.

So for the ‘Clinicians on FHIR’ event that we’re holding at the HL7 Working Group Meeting in October, we’re going to try a different approach. We’re developing a basic ‘chat’ application that is hierarchically organized, and also integrated with the tooling – clinFHIR – that participants in the event use. If all goes well, it’s also going to help in running ‘virtual’ events in the future, where people are not in the same place.

This post describes how the chat application is structured.

Read more of this post

Clinician Connectathon

Well, we’ve just finished the second Clinician Connectathon. I wasn’t able to attend in person, but was able to dial in from home (New Zealand) to participate and it all worked out really well.

The tooling mostly behaved itself (we had a few server issues) – which was a relief!

We’ll do a more complete review later on, but for me the take away is that these events are really worth continuing (and the others seemed to agree with this), and that the tooling needs to continue to evolve – perhaps to move away from a strictly resource focussed perspective as it is now, to a more functional one. We also need to increase the range of resources, supported properties on those resources, save more stuff to FHIR servers & improve the way we support profiling. No pressure…

We’ll continue to work on this, and we’re encouraging people to try the tooling out between events so that bugs and be squashed, enhancements can be developed, deployed & tested prior to the actual event and we can maximize the value of getting clinical folk together to talk FHIR.

If you’re interested, the tool is available here, and I do encourage you to go have a look and give us feedback (you can do that in comments to this post for the moment- we’ll figure out a better way soon). We’ll also be working on the documentation…

So, on to Paris in May! (and I’m off for a sleep…)

Clinical Scenarios in FHIR – II

In a previous post we talked about the clinical connectathon coming up at the next Working Group Meeting, and described how we could use FHIR resources to represent one of the scenarios – the chronic care scenario. Looking back, much of that scenario was around the creation and maintenance of a Care Plan (which might be worth a re-visit at some point). In this post, we’re going to shift gears a bit and look and another scenario created by the Patient Care Working Group – the Acute Care Scenario.
Read more of this post

Using FHIR to record Immunizations

At the last Working Group Meeting we agreed that it would be a good idea to think about holding a ‘clinical connectathon’ where the focus of the event was on how we can use FHIR to meet real clinical scenarios, rather than the more technical, developer based focus of the current connectathons.

The idea is that as we progress through the ‘maturity’ stages of FHIR towards a normative standard, we want to be really sure that it’s fit for purpose, so having an event that takes clinical scenarios, and then ensuring that the standard supports those scenarios makes a lot of sense.

At the moment we’re at the stage of choosing representative scenario’s and then matching the current FHIR resources against those scenarios to see how they work, and identify gaps. I’ve been given the task of looking at paediatric immunizations, so thought I’d share the thinking here. (Actually I volunteered – after all, how hard can it be? <s>)

So lets set the scope of the discussion.

Most countries have a standard paediatric immunization programme (or protocol) – a set of vaccinations that applies to most children, and specifies the ages at which they are given. This can actually get quite complicated – especially when the programme changes and there is a ‘catch-up’ set of vaccinations required for children partway through the programme.

This programme is applied to a specific child, and can be customized for that child – for example they may be allergic to a particular vaccine or to eggs (which influences what vaccines they can be given). This is, in effect a Care Plan (or at least part of a care plan). If the care plan is altered in this way, then there needs to be some record made of why this was done – both for the patients clinical record, but also important for reporting.

When a vaccine is actually administered, the plan is updated and an entry is made in the clinical record for the patient, which includes such details as the date given, person who gave it, vaccine type and other details such as the manufacturer, lot number, site etc.

In some cases, the childs parent will decline to have their child immunized. Again, the reason for this needs to be recorded in the notes, and the plan updated accordingly (it may be the whole plan that was declined, or just a part of if – a specific vaccine).

So here are the main use cases (excluding the ‘workflow’ use cases – the process of recalling the child for the immunizations):

  • Create the childs initial immunization plan from the standard protocol
  • Administer a vaccination, updating clinical record and plan
  • Record any reactions that occur – updating the plan if required
  • Record that a vaccination was declined – updating the plan and the record
  • Update the plan to reflect personal issues – such as allergies – or additional vaccines required
  • Update the plan to reflect a change in the standard protocol (which will include ‘catch up’ vaccinations)

(I’m sure there are others, but these will suffice for this discussion).

So how does FHIR rate against these requirements?

Let’s start with the simple stuff: recording an immunization.

The Immunization resource is used to record the actual administration of a vaccine (or not, as we shall see). It has elements to record the details of the vaccine given, who gave it and when it was given. One thing it doesn’t have is a reference to the Encounter in which it was given, but that’s easily managed by an extension. There are a number of things worth calling out about this resource:

  • vaccineType is the vaccine given (or refused)
  • refusedIndicator is a required Boolean that lets you record that an immunization was offered but declined by the parent. If true, you can use explanation.refusalReason to record why it was refused.
  • reported lets you record vaccinations that you have been told have occurred, but haven’t given yourself.
  • reaction is an element that allows you to record any adverse reaction that occurs subsequent to giving the vaccine. (Of course, this field would be filled in as an update to the Immunization resource – not at the time of creation – unless you are slow at updating your records or the reaction was particularly quick! You’d create the AdverseReaction resource and then reference it from the immunization)
  • performer and requestor record details of the people administering the vaccination.
  • site, route, doseQuantity – how much was given and where
  • manufacturer, lotNumber, expirationDate – details about the vaccine
  • vaccinationProtocol allows you to record the protocol/s that this immunization is a part of – including where it is in a sequence of vaccinations, and the disease being protected against.

Retrieving a childs immunization history is then simple:

GET [host]/Immunization?subject={patientid}&refused=false

(Note I included the refused in the query to only get back the actual administrations. I could just as easily leave that out and manage client side if I wished to – for example – indicating immunizations that had been declined)

Recording the plan

So recording an immunization is straightforward  – what about the set of immunizations that a child should receive – their ‘immunization plan’?

Looking at the spec, there would appear to be a couple of ways – the ImmunizationRecommendation or  Careplan.

Lets talk about ImmunizationRecommendation first.

FHIR defines this resource intended specifically for holding details about what immunizations a patient should receive (Actually it states “A patient’s point-of-time immunization status and recommendation with optional supporting justification“, so we might be on the wrong track, but let’s run with it for the moment…)

Each resource is specific to a patient, and has one or more recommendation elements (each representing a specific vaccine), each with one or more dateCriterion elements giving the dates on which each dose of the vaccine is due.

Properties to callout:

  • recommendation is the element storing details of a single vaccine.
  • recommendation.vaccineType is the actual vaccine to give
  • recommendation.doseNumber is which dose this is in a series. For example, if the vaccineType is ‘pneumococcal’ and there are 4 doses to give, then this recommendation element version might be the date for the 3rd dose.
  • recommendation.forecastStatus indicates where the child is with respect to the protocol – ie due or overdue.
  • recommendation.protocol has more details about the protocol (though I’m not quite clear about how some of these elements differ from those in the recommendation – eg the Recommendation.doseNumber and Recommendation.protocol.doseSequence.

So you can imagine a sequence as follows:

A new child is born (hurrah!). A new ImmunizationRecommendation resource is created for them from the standard protocol (more about that soon). In the most common use case, the ImmunizationRecommendation would simply be a ‘copy’ of the immunization protocol.

Each time an immunization is given, an immunization resource is created and the ImmunizationRecommendation resource updated by removing the appropriate dateCriterion element. (an alternative would be to use an extension to indicate that the vaccine had been given – this would need to be a modifierExtension as it changes the meaning of the element).

Thus the ImmunizationRecommendation resource for a patient has a number of versions representing updates to the plan (generally when an immunization is given, but also updated when declined.

Now let’s have a look at the careplan.

We’ll model this as a separate careplan resource for immunizations. We could incorporate immunization elements in a single larger plan if we wanted do, but a separate plan with a goal of ‘keeping up to date with immunizations’ does seem a bit cleaner, especially if a patient has multiple plans stored in multiple systems).

Properties to callout:

  • Goal is what we’re trying to achieve with this plan.
  • The activity is where we record the vaccinations that the child should receive – one entry per vaccine dose.
  • Activity.simple has the details:
    • Category (this would have the value ‘drug’, though we might want to add ‘immunization’ to the list of possible values )
    • Code – not sure what we’d use this for – the product would indicate the actual vaccine
    • Timing – when the dose needs to be given.
    • Product – this would be the actual vaccine
    • Quantity – how much to give.

The actual sequence is going to be much the same as that for ImmunizationRecommendation.

A child is born and an immunization careplan created for them from the standard protocol. The plan would have one activity for each dose of a vaccine that is required.

As the child progresses through the plan, immunization resources are created and the plan updated. We can be a bit more creative by using the activity.status code though – setting that value to ‘completed/cancelled’ as an immunization is given or declined. This would mean that the status of each dose is immediately obvious from the plan.

(Alternatively we could delete the activity from the plan as it is completed, but that just doesn’t feel right when we have a status to record the outcome.)

What might be quite nice would be to reference the actual immunization resource from the activity using an extension once it has been given or declined.

We’d probably create a profile against careplan to specify the appropriate coding systems, add extensions (like a reference to the actual immunization) and remove the properties that don’t make sense for immunizations .

So which to choose?

Well, to my mind the careplan seems the logical choice.

  • It is where all other planning activity is going to be recorded (either in a single common plan or a collection of them).
  • It has an element (activity.prohibited) that we can use to indicate that a vaccine should not be given – that we might want to use if there is a serious allergy to a vaccine
  • It keeps a nice history of our activity against the plan – and referencing the actual Immunization would be useful here.
  • The timing element can be a period rather than a fixed date – useful to indicate the range of dates when a vaccine can be given to be effective.
  • ImmunizationRecommendation feels like it is more intended to answer the question ‘What should this child receive now (and are they overdue)?’ or ‘how well is this child doing with respect to their immunization plan’ rather than a formal plan of care for an individual.
  • There are elements in ImmunizationRecommendation that don’t really fit in this context – like recommendation.doseNumber and recommendation.protocol.doseSequence

In fact, after I wrote this post the careplan seemed such an obvious choice that I nearly went back and edited out the ImmunizationRecommendation as an option, but in the end decided to leave it there to record how I came to this conclusion.

So we’ve talked about how to record immunizations and how to store the immunization plan for a child. What we haven’t talked about is how to record the standard immunization protocol and apply that to a child – and we’ve got a few options to consider. This applies equally to changes to the standard protocol, and how that effects the plans of children already receiving immunizations.

We should also think about reporting – most jurisdictions have a requirement to report at a population level the overall status of immunization so we want to be sure we’ve covered that off as well.

However, this post is already over-long so we’ll consider these in the next post.

Comments (as always) welcome!

FHIR Connectathon

Kai has done a neat video of the latest FHIR connectathon. Kinda weird to see yourself on camera though!

FHIR Questionnaire: Connectathon 6

Note that since this post was written, the Questionnaire resource got split in 2 with the Questionnaire being just a template, and the QuestionnaireResponse holding the data. More on that here.

The theme for the next FHIR Connectathon has just been decided by the FHIR Management Group, and this time round we’re going to explore the Questionnaire resource. The reason for choosing this is that there is interest in this resource from a number of significant organizations in the healthcare space, and because it supports one of the core requirements in healthcare – the ability to collect information using a form, and to extract information from that form to populate or update a medical record, while always keeping a ‘copy’ of the form.

It’s important to appreciate that the purpose of the Questionnaire is in the collection of information – not to act as a ‘repository’ of that data for later searching. In other words, if the Questionnaire collects something that needs to be recorded outside of that form – like a Condition – then the correct thing to do is to create a formal Condition resource and store that. Searching for data within the Questionnaire is certainly technically feasible, but is discouraged – the spec doesn’t even define any standard search parameters for this.

It is still possible to refer to a Resource from the Questionnaire  – you might want to do this if sending a completed Questionnaire to someone else  and wish to include the created resources in a bundle – but to do that you must have already extracted the data, created the resource, and then placed a reference to it within the Questionnaire. In some ways, this is like a FHIR Document – where the Questionnaire is analogous to the Composition resource – although the purpose is quite different. And, like a document, you can include all the resources in a bundle and sign it. (We talked about signing in the post on tamper proof auditing)

If you want to be able to record that the resource was created from data in a questionnaire, then the Provenance resource should be used. would refer to the resource, and Provenance.agent would refer to the Questionnaire.

At a high level, there are at 2 ways to use the Questionnaire:

  • As a ‘template’, containing only the questions – and potentially layout. (Template is a really overloaded term unfortunately).
  • As a ‘form instance’, containing the questions and the answers to those questions, or with the answers only (in which you would need to refer to something else to render it).

The Questionnaire.status property is used to distinguish a specific resource – the diagram below shows how this works.

questionnaire workflow

When it comes to using a Questionnaire to create a form, a common workflow might be:

  1. Select a blank Questionnaire from a set established as templates. These would be Questionnaire resources with a code of ‘published’.
  2. Prepopulate the Questionnaire from data sources if available. For example, you might want to include the current medication list or conditions.
  3. Render the Questionnaire as a form for the user to complete
  4. Save the completed Questionnaire as an interim Questionnaire.
  5. Complete the Questionnaire.
  6. Construct any other resources from the Questionnaire, and place a reference to them in the Questionnaire.
  7. Save the Questionnaire resource

To store a Questionnaire, you save the resource in the data store in the same way as any other resource. As described above, there may be other resources that were created on the basis of data entered in the Questionnaire that can be referred to from the Questionnaire.

To display a completed Questionnaire (form) to an end user, the simplest way is to store that rendition in the text property of the resource. In that way, any system with minimal FHIR compliance can retrieve and display it. This also gives the creator of the form control over the display format, which senders often require. Of course, as the resource contains structured data it can be rendered in a different way if required – e.g. on a mobile device. If storage space is an issue, then an alternative is to store the answers only in the Questionnaire – with a minimal text property – and require the consumer to retrieve a display template and render locally. The same applies to the a template: you could include the layout in the text element, or require that the recipient render it.

Well that’s an overview of the Questionnaire resource. In the next post we’ll dig a bit more into its structure, and go over this workflow in more detail.

Decomposing a FHIR document

Scenario 2.3 of Connectathon talks about a server ‘decomposing’ a FHIR document. This is another of those huge topics, as it is all about using the document as a ‘carrier’ for information that is used by a recipient to update their own data stores, rather than simply storing it as a ‘blob’ to be displayed to a user on request.

The issue is not so much a technical one – that’s relatively straightforward (though one of the more complex in FHIR) – but rather relates to the purpose of a document as a ‘summary at a point in time’ – or as a ‘snapshot’, rather than a mechanism to ‘transfer state’.

Read more of this post

Server processing of FHIR documents: Connectathon

In this post we’re going to think a bit about how the server might process a document that it receives. This is a massive topic, and certainly not one that can be covered in a single post – or by any one individual! Apart from anything else, there are lots of different possibilities – all legitimate in specific circumstances.

This is an important concept for FHIR – it doesn’t seek to drive any particular design or architecture – rather it attempts to support how data is moved around now, and how it may be done the future. It’s up to individual implementations to decide the details, but using common ‘building blocks’.

Read more of this post

Creating a FHIR document for the January Connectathon

I had intended to talk in some detail about the Composition resource next, as this is one of the key resources for a FHIR document, but because the January connectathon is getting close I’m going to do a series of posts to directly support people attending connectathon, and wanting to experiment with the document track. I’m planning 4 posts in this series:

  • How a client would create a FHIR document (incidentally for the remainder of this series, I’m going to refer to a FHIR document just as  ‘document’, so when you see this, I’m NOT talking about CDA. Later posts will talk more about the relationship between the two).
  • How a server could process a document. There are a few possibilities…
  • How to find the document on the server later, and render it to the client.
  • A wrap up on the Composition resource and anything else left over.

I do intend to spend a lot more time on FHIR & CDA, but this should at least cover the basics.
Read more of this post