Site icon Hay on FHIR

FHIR Messaging: Clinical data from ADT Messages

In the last post, we started to think about how we might be able to capture clinically useful information (naturally as FHIR resources) from the HL7 v2 messages that are used within many hospitals. These messages are used to move information between the various components of a hospital such as the PAS (Patient Administration System), the RIS (Radiology Information System), the LIS (Laboratory Information System) and so forth.

A common pattern is that the ‘downstream’ systems (LIS, RIS) ‘subscribe’ to these messages emitted from the PAS – generally via an Integration Engine. So all we’ll do is add ourselves to the list of interested parties, and we’ll get a copy of each message as well.

And actually, there’s no real reason why we should confine our attentions to just one hospital – if there are multiple co-operating hospitals then there’s no reason why we can’t receive messages from all of them, though we do need to be careful with identifiers (patient and visit) as these might overlap between providers.

Here’s what it might look like, with the arrows representing the flow of v2 messages:

The resources we identified that we could get from this data were:

Now we’re said that we’re in a messaging paradigm now, but what does that actually mean?

Well, as the diagram above shows. we are receiving messages that have been sent by another system (generally the PAS) in response to real world events that occur as the patient is treated in the hospital. This has a couple of implications for us:

(Actually, in real-life we also need to consider how to manage ‘out of order’ messages – what do we do when, say, a bed transfer message arrives after a discharge message? This is an implementation issue, and so we’re going to ignore it in this discussion, but if you’re doing this for real then you will need to decide what strategy you are going to follow – for example you could reject such messages and make the sender decide what to do, or you could make a decision based on the date of the message – or anything else, an exercise for the reader 🙂 )

So what does our model look like? Well, here’s a first draft:

Note that all the ‘clinical’ resources have a link back to the encounter where we got them from. We’re going to need this to be able to properly manage changes that might occur due to workflow issues, and also as a kind of ‘provenance’ – knowing the source of clinical information is always important. (Actually, there’s a formal Provenance resource that we could use if we wanted to).

In most of the resources there is a property that makes sense:

We haven’t indicated any Patient, which all of the resources will have a reference to. As we’re getting information from different sources which will have their own patient referencing systems, this is going to need some thought which we’ll go into in the next post.

OK, so we have the model – let’s think about what each message is going to do to our model (we’ll come back to the question of linking all messages to the same ‘encounter stream’ later on).

There are a lot of messages to consider – over 60 of them in the 2.4 spec (which is the version we’re using)! The actual messages that are used will be different in each implementation, and we don’t have space to consider them all, so we’ll pick a selection that will highlight the major factors that we are going to need to consider.

The table below lists some of these messages and the impact on our model. For readability, we’ve just included the event code, so A01 is actually ADT^A01.

Some of these messages are reasonably straight forward to process – and others are not!.

(btw – it’s a good idea to read this in conjunction with the v2.4 spec – it’s in chapter 3 – Patient Administration)

Message Purpose Has clinical data Description
A01 Admit/Visit Notification yes This is the message that is sent when a patient is admitted to the hospital – ie assigned to a bed. When received by the system it will create a new Encounter resource, along with any clinical data.
A02 Transfer a Patient No This occurs when a patient changes physical location – for example they are moved to a different ward. It will update the encounter resource, but not the clinical data.

Interestingly, the spec notes that if there is any clinical data that changes, then the A08 message should be sent.

A03 Discharge/End Visit some Sent when the patient is discharged. It will update the Encounter, and may include diagnosis & procedure information (but not allergy). Again, the recommendation is to use A08 if needed to update associated data
A04 Register Patient yes Similar to the A01, this indicates that the patient is at the hospital (eg in the EC – Emergency – department) rather than being formally admitted. We would create a new Encounter if we get this message.
A05 Pre-Admit a Patient Yes Will also create a new Encounter (and clinical data). Used during a pre-admission when the patient is examined before the actual date that they are admitted (this is common for planned – or ‘elective’ procedures).
A06 Change an Outpatient to an Inpatient yes Used when a patient who is being seen as an outpatient is admitted. For example someone is in a cardiology outpatient, and their condition is so serious that they are immediately admitted.

Interestingly, the spec stats that this may either change the existing encounter (the outpatient one) or create a new one. From our perspective, this raises the question of how to identify an encounter – which we will talk about soon. It also shows how the v2 spec is used in different ways for different implementations – you need to check these things!

A07 Change an Inpatient to an Outpatient yes I’m not quite sure when this would be used – a discharge would seem more logical, but I guess there are systems that do it this way. Like the A06, this might either change an existing encounter or create a new one.
A08 Update Patient Information yes This changes the information associated with the patient, but which doesn’t effect the encounter. For example a new allergy is discovered. The encounter resource will be unaffected, but the clinical resources may well be.
A11 Cancel Admit / Cancel Visit Notification no This cancels an admission (A01) or a registration (A04) – either because of error, or because a decision is changed.

We’ll set the status of the encounter accordingly – but an interesting question is what to do with the clinical data. Should we invalidate that as well?

A12 Cancel Transfer no When an A02 (transfer) is cancelled. The encounter status will be updated, but the clinical data we’ve extracted can remain.
A13 Cancel Discharge / Cancel End Visit yes Similar to the A12 event. The encounter only is updated
A28 Add Person or Patient Information yes This is similar to the A08, but is specifically intended to update patient related data between systems that may have different master patient databases. Like that event, the clinical data but not the encounter will be updated.
A31 Update Person Information yes This is specifically intended to update patient information in an Enterprise Master Patient Index ( EMPI). We can use these messages to update our patient store so we know who the patient identifiers refer to, though we could also extract the desired information from the PID segment of any of the messages.
A37 Unlink Patient Information no This is an ‘unlink’ message – see A40 for discussion. (There used to be an A36 – patient merge message that the A40 replaces)
A38 Cancel Pre-admit no Cancels an A05. The same considerations as for A11
A40 Merge Patient – Patient Identifier List no This event indicates that 2 patient identifiers are actually the same person, and we need to ‘merge’ them together. Patient identity is a really complicated topic that we’ve dodged so far, but this time we can’t. Having said that – how we manage it is going to be entirely dependent on how we implement patient identity.
  • If we have an architecture where, at read time, we take the supplied identifier, locate all the merged identifiers, and return all the data related to all those identifiers then we’re sweet.
  • If we only look up on the single identifier, then we need to go through existing data and change identifiers – in a way that will allow an ‘unmerge’ to work

Either way it needs careful thought, and the v2 spec has quite a lot to say about it.

A45 Move Visit Information no Another potentially tricky one. The spec states that this is a ‘move at the visit identifier level’ – where the ‘patient account’ associated with the visit has changed. In other words – the patient has changed for this visit.

For us, it probably just means that the Encounter.subject property needs to be switched to the correct patient, but anything that involves patient identity has ramifications that we’ll need to think through.

We also need to think about the effect on the clinical data we’re extracting: do we change the subject there as well? Or – do we assume/mandate that an A08 message will come though and change it? If we do, then we’re assuming that an A08 is able to change the identifier (which is not mentioned in the spec), so it may be safest to change the subject property there as well.

A50 Change Visit Number This actually changes the visit number – the identifier that indicates that a sequence of messages is about the same visit. The actual effect for us will simply be to update the encounter

So there’s a few things we’re going to need to give careful thought to – and these are likely to be ‘implementation dependant’ – i.e. they will vary between different hospitals.

So there are a few things to think about (and I’m sure many others that we haven’t listed here). To keep things moving we’ll make the following assumptions (your assumptions may be different):

In practice of course, we’d need to ensure that the source systems abide by these rules. If they don’t, then we’ll either need to change our system – or possibly use an Integration Engine to update messages from specific hospitals to make them compliant. For example, if a particular hospital does not emit A08, but does include a snapshot of clinical data in all update messages (like an A02) then the Integration Engine could create an additional A08.

So let’s take another look at our list of supported messages and what they are going do in our system.

Message Purpose Action in our system
A01 Admit/Visit Notification Create a new encounter and all related clinical data
A02 Transfer a Patient Update the Encounter properties
A03 Discharge/End Visit Update the Encounter properties
A04 Register Patient Create a new encounter and all related clinical data
A05 Pre-Admit a Patient Create a new encounter and all related clinical data
A06 Change an Outpatient to an Inpatient Update the Encounter properties
A07 Change an Inpatient to an Outpatient Update the Encounter properties
A08 Update Patient Information Update the clinical data associated with this encounter. Note that this can change the subject associated with those resources as well.
A11 Cancel Admit / Cancel Visit Notification Update the Encounter properties
A12 Cancel Transfer Update the Encounter properties
A13 Cancel Discharge / Cancel End Visit Update the Encounter properties
A28 Add Person or Patient Information Update the clinical data associated with this encounter
A31 Update Person Information Not quite sure about this one yet. It’s not really related to a particular encounter, so we’ll think about it a bit more when we start to consume other messages. For now, we’ll ignore it.
A37 Unlink Patient Information Our patient identity system will no longer assume that these two identifiers refer to the same person.
A38 Cancel Pre-admit Update the Encounter properties
A40 Merge Patient – Patient Identifier List Mark the two identifiers as being the same person. (The message contains the ‘surviving’ identifier). We won’t actually merge them – we’ll just link them together. That way we can ‘unmerge’ – A37 – them later.
A45 Move Visit Information Change the encounter.subject to reference the new patient identity
A50 Change Visit Number Change the encounter.identifier property. Of course, an encounter may have multiple identifiers so we’ll need to make sure to change the correct one!

That’s quite a chunk to think about! And hopefully explains why workflow is so important, and why this stuff can be so complicated! We’ve just looked at a small selection of messages – and all we’re really doing is to maintain a store of resources – imagine if we were writing a PAS ourselves!

In the next post we’ll delve into architectural issues and think about what we need in our FHIR server to support these messages. Oh, and if you disagree with anything in the post – feel free to make a comment!

Exit mobile version