‘Default’ namespaces in HL7 v2

So I had an interesting question this week about coded values when importing data from HL7 v2 messages into a data store, and then subsequently exporting them in FHIR interfaces.

The specific question was what should the ‘default’ namespace be when the namespace is not specified in the v2 message?

The message and field in question is the AL1-2 “Allergen type Code” that you find in ADT messages. It’s a CWE (Coded With Extensions) datatype, and there’s a user defined table of suggested values – number 0127.

I must admit that my first reaction was ‘”It’s a user defined table with example values so just use the namespace (or system) for that table and add the value to it”. But on reflection (to be honest, after discussion with a colleague more detail orientated than I am – you know who are Rod!) that’s wrong.

Let’s start with how we need to correctly represent the data in the repository. Being a coded element, we need to have (at a minimum) the Code and the Code System  from which it is defined. For example if this were a diagnosis code, we might use SNOMED to encode it – in which case the coding system would be ‘SNOMED’ (or the url that represents SNOMED) and the code for the specific concept in SNOMED.

So what is the coding system here? Well, it’s a user defined table, but there are a number of example values in the v2 spec, so we can think of that as the codesystem. That’s all well and good, but what happens when we get a value that’s not in the spec? What codesystem do we use then? Can we just add the code to the codesystem/table?

The short answer is no, we can’t. We’re not the custodian of the values in the codesystem – HL7 is. To help understand how we solve this, take a look at the following picture (which we’ve seen before) from the FHIR Spec (the overall concepts are the same in v2 & FHIR)

terminology-module-relationships (1)

Note that the data in the ‘instance’ (lower right – which will be the v2 message and its representation in the database) refers directly to the CodeSystem, while the ‘element definition’ (upper right – which is the equivalent of the v2 specification) refers to a ValueSet (that in turn refers to a CodeSystem – actually one or more codesystems).

An important point here:

The actual definition of a code – and the details that need to be in the repository – come from the CodeSystem. The ValueSet is just a selection of codes from one or more CodeSystems in a given context

So applying this to the v2 spec, what is happening is that the contents of a given field is bound to a ValueSet – which happens to include all the values from a CodeSystem (being the table in the spec). And in this case, it’s a user defined table with ‘suggested’ values – and the datatype is CWE (Coded With Extensions), so the binding strength in FHIR terms will be extensible (we really should use these values if the meanings match up, but we can add others).

Here’s a screenshot from the v2 spec:


In the top table seq 2 refers to the ‘ValueSet’ 0127, which in turn refers to the contents of the ‘CodeSystem’ 0127 (the lower table).

This distinction between ValueSet and CodeSystem is really important – and really confusing! (especially when they seem the same…)

Think of the ValueSet as being a ‘design time’ thing – “here are the codes’ you can/should use”, while the CodeSystem is the definition of an actual code in a real message. The ValueSet is really just a pointer to the actual codes defined by the CodeSystem (even if they seem to be the same thing) – it’s the concepts from the CodeSystem that will be in the message/database – not the ValueSet.

So with all that background, how do we answer the original question? What do we do if we get a value in the AL1-2 field that doesn’t have a namespace? Well, the right thing to do is to see if the value exists in the HL7 Table (CodeSystem). If it does, then it’s likely safe to assume that the CodeSystem is the HL7 one – so we can use that. But if it doesn’t, then we need to associate it with another CodeSystem when we store it. How we do that is up to the implementation. We could:

  • Reject the message and make the sender choose a value from the defined set (a bit harsh)
  • Use codes from an existing CodeSystem like SNOMED – always preferable if possible
  • Create a new CodeSystem for the different codes. This could be agreed in advance with the message sender – or we could add it automatically and add descriptions later. Note that the CodeSystem would likely be specific to the context (“Allergy types not in the spec that we have agreed we’ll use”) – though it doesn’t have to.

But, at the end of the day, the data that we store needs have both a code, and a reference to the CodeSystem where that code is defined.

So this covers getting the data into the data store in a form where it can be manipulated. There are other issues around exposing them in a FHIR API – we can think about that later.



About David Hay
I'm a Product Strategist at Orion Health, Chair emeritus of HL7 New Zealand and co-Chair of the FHIR Management Group. I have a keen interest in health IT, especially health interoperability with HL7 and the new FHIR standard.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: