HL7 for Busy Professionals
Page 4
HL7 v3.0 is being implemented in places where there are little or no existing systems. Governments in Europe have used v3.0 to create new healthcare networks, and in Canada, v3.0 adoption is being driven by the federal and provincial governments’ initiative to create drug-information networks and registries of healthcare providers. In the United States, the CDC has implemented some networks with v3.0 messaging, but overall the adoption remains low.
Given the widespread adoption of v2.x and its incompatibility with v3.0, it will be a long time before v3.0 replaces it as the dominant standard. And even then, v2.x will exist long into the future. If it ain’t broken, organizations are not going to fix it. My first job was production support of an S/390 IBM mainframe. Its software code was written in COBOL in the 60’s. No one is going to replace that code as long as it does its job.
Other Healthcare Standards
People working in healthcare IT know that HL7 is not the only standard they have to deal with. X12, SNOMED, ICD-9/10, DICOM, there are a lot of standards vying for their attention.
Generally speaking, most standards have been developed for a particular healthcare area such as medical imaging or insurance or for some kind of classification. Although HL7’s area is clinical and administrative data, it can handle the messaging requirements (internal and external) of an entire organization. This distinguishes it from other standards, which are primarily focused on the needs of a particular area.
Take the example of DICOM (Digital Imaging and Communications in Medicine). It is the standard used by PACS and other imaging systems to transmit, retrieve, and store medical images. But DICOM can only be used between imaging systems. If a different system needs an image, it will have to be translated or embedded within an HL7 message.
Similarly, the X12N standard is used only for transmitting patient insurance and financial data to the insurance company. If additional patient information has to be sent, an HL7 message containing the information will have to be embedded within the X12N message.
Then there are standards just for classification, which have nothing to do with messaging.
ICD-9/10 (International Classification of Diseases) is a standard that clinicians use to classify diseases, injuries and causes of death. Revision 10 is the most current version, which also includes codes for classifying health-risk factors (occupational, environmental, lifestyle etc.). ICD codes are regularly sent as data elements in HL7 messages.
LOINC (Logical Observation Identifier Names and Codes) is a standard for classifying lab orders and tests. In this system, every possible lab test has a unique, three to seven digit ID number. An HL7 order message will only need to have this unique ID in its “ordered test” field for the receiving system to know which test has been ordered. Similarly, when the result is sent back, LOINC codes are used to specify the test that the result is for.
LOINC has more than seventy thousand codes. Each code corresponds to a different kind of lab test. For example, there is a test called Serum Sodium or Blood Sodium Level or Sodium-Blood, depending on who you are talking to. Its LOINC code is 2951-2. When this code is sent in an order message, the receiving system knows exactly that the test is to measure the concentration of salt in the blood. It is unambiguous and does away with the confusion of different names. If you have had a lot of salty food, your reading for 2951-2 will be north of 140. (The normal range is 135–145).
Then there is SNOMED-CT (Systematized Nomenclature of Medicine-Clinical Terminology), which is like a thesaurus for medical terms, diseases, anatomy and procedures. It uses ConceptID and DescriptionID to define codes, synonyms, and descriptions of medical terms. For example, myocardial infarction is a concept (ConceptID 22298006), which refers to infraction (death of tissue) in the myocardium (muscular wall of the heart).
These standards take you deep into the clinical world. If you not queasy about syringes and scalpels and stitches then keep wandering. For me this much information was more than enough and I never had any issues with these standards. As long as you have a rough idea what the content of a field represents, there won’t be any problem working with these standards.
This brings us to the end of part I. We have covered the background information and now it’s time to look at the standard itself. Even if you only read the next two or three chapters, it will give you a fairly good idea of the standard.
PART II
Digging Deeper
5. Basic Concepts
So now you understand that HL7 is an application layer (level 7) protocol that clinical systems use for sharing information. Also, because of a lot of optional elements and customization, HL7 is almost a non-standard standard. We can’t just send any HL7 message to a system and expect it to understand the message.
When two or more systems are integrated, they have to first agree on the types of messages that will be exchanged and triggers events that will be supported. All this information (and more) is then documented in an Interface Specification document before actual work begins to integrate the systems.
If you have an environment where HL7 messages are used, then all this information on message type, trigger events, acknowledgement etc. is there somewhere in the form of one or more interface specification document.
You will need a good idea of some basic HL7 concepts before you are comfortably able to navigate these documents and other HL7 related artifacts. In the following pages we will cover these basic concepts.
Unsolicited Messages
HL7 messages are generally unsolicited. Not always, but in the vast majority of cases. Before we get to why most messages are unsolicited, let’s see what kind of a beast an unsolicited message is.
Un-solicited or not solicited is the opposite of solicited. The word solicit means “to ask for something from someone”. So its opposite, unsolicited, will probably mean “getting something from someone without asking for it”.
I remember Toronto’s Mayor Rob Ford landing in hot water while soliciting donation for his private football foundation. He was using City of Toronto letterhead for the purpose, not realizing you can’t use the power of the office to solicit donation.
Similarly, if a system explicitly asks another system for a message, then that is soliciting. Messages in this case are solicited messages.
A database query is a good candidate for solicited messages. If you want to know the number of inpatient admissions for the day, the information is solicited as a query to the system, which responds with a message containing the number of admissions for the day.
Now imagine a world where all HL7 messaging is like this. After placing an order for a lab test, the system in the doctor’s office will keep pestering the lab system for the test result. If the result is not ready, there is nothing the lab system can do. It doesn’t have the information. This is an inefficient way of communicating that wastes processing power, degrades performance and is a real annoyance – like kids in the backseat constantly asking “Are we there yet?”
The alternative is an unsolicited message. In this case, the Lab system automatically sends the test result when it becomes available. It doesn’t require the system placing the order to keep asking for the result. By placing an order, the system has implicitly indicated that it wants the result. Or in other words, it receives the result as an unsolicited message.
This is a much better way of communicating. It is an optimal solution where a message is created only when it is needed. And for that reason, most HL7 messages are unsolicited messages.
Message Type
While working with HL7 you will come across statements like, “this is an ADT message” or “we can process an Order message”. These references, ADT and Order, are simply different message types. Message types are used in HL7 to group and classify similar messages.
If you are thinking HL7 message types are probably based on real world organization of a healthcare environment, then this is a good time to throw out that idea.
Instead of mirroring real world, HL7 message t
ypes are organized by their function. Take the example of an order message. It doesn’t matter if the message is for a lab or a pharmacy, as long as the message is an order for something, a test, a medication or even housekeeping, it is an order message type. Similarly messages that deliver results, be it a lab test result, an X-Ray or an ultrasound, they are all result message types.
HL7 defines thirteen different kinds of message types but you don’t really have to know them all. Real life usage of HL7 follows the 80-20 rule of the Pareto principle (example, 80% of accidents are caused by 20% of drivers or 80% of sales come from 20% of customers). Likewise, most HL7 messages use only a few of the message types available. Most healthcare organizations use only this small subset of message types and if you become familiar with the top three or four, you will have covered between sixty and seventy percent of real world implementations.
So what are these most commonly used message types?
As you know, HL7’s area is clinical and administrative data. So it is no surprise that the most commonly used message type is patient-administration. This is the message type that groups together messages that have anything to do with managing a patient - admitting, discharging, updating their information, transferring to another unit etc.
The next two most commonly used message types, in my experience, are Order Entry (orders) messages and Observation Reporting (results) messages. But of course this can vary from place to place.
Another thing to know about message types is the Message Type Code. This is a three-character code that is used as an acronym for the message type. For patient-administration, there is just one code: ADT (short for Admission, Discharge and Transfer). All patient-administration messages are ADT messages.
For order-entry (orders), there are a few different message type codes, depending on the type of order the message is carrying. The code ORM is for the general order message. Although it has been discontinued in newer versions of HL7, ORM continues to be heavily used in older implementations. In addition to ORM, there is OML for lab orders, OMI for imaging order, OMD for dietary order and so on.
The observation-reporting (results) message type has a couple of different message type codes as well, but the code ORU is the one that is most commonly used. The code OUL has something to do with lab system automation and not used much. We won’t waste our time on it.
The HL7 specification document (HL7 spec) is organized by message types. If you want to know more about a particular message type and its codes, all you have to do is flip to the chapter for that message type.
Trigger Event
HL7 messages are trigger-event driven. What does that mean? It means that an HL7 message is created only when something happens (an event) in the real world. This “something” in the real world is the trigger that sets the wheels in motion.
For example, admitting a patient is a real world event that triggers the creation of an HL7 message. When the hospital staff completes the admit form and hits enter, it sets off a chain reaction in the registration system that leads to the creation of the HL7 message. The content of the message depends on the event that triggered the message creation. In this case, it contains details of the patient being admitted.
Not every event in the real world triggers message creation. HL7 defines specific real world events within the context of a message type that can trigger message creation. It is these events that are called trigger events.
There is a long list of trigger events that map to real world events. For instance, ADT defines over sixty different trigger events. But this is a bit of an outlier because other message types don’t have so many trigger events.
Even with so many trigger events, there could still be a situation where a message needs to be generated for a real world event that doesn’t have a corresponding trigger event. In such cases, one will need to get a little creative and re-purpose another close enough trigger event for the situation.
Just like message types, trigger events have their own three-character Trigger Event Code. But there is a difference. Message-type codes are all uppercase letters whereas for trigger-event codes, the first character is a letter and the next two characters are numbers, such as A01 (patient admit) or A02 (transfer patient).
Together, a message type and a trigger event uniquely define an HL7 message. It is generally written by joining together the message-type code and trigger-event code with a caret (^) symbol. So, a patient admit HL7 message is represented as ADT^A01. A patient transfer HL7 message is represented as ADT^A02 and so on. Often people drop ADT and just refer to the messages as A01 or A02.
When two systems are being integrated, it is decided beforehand which HL7 messages will be sent. Let’s say a hospital is implementing a new pharmacy system, which will be integrated with the hospital EMR. This is to ensure that when a medication order is placed, the pharmacy system has the information to confirm that the order is for a valid patient.
It means the system will need to know when a patient is registered and when that patient is discharged from the hospital. Or in other words, the pharmacy system will need ADT^A01 (register patient) and ADT^A03 (discharge patient) HL7 messages from the hospital EMR. To put it even more simply, the pharmacy will need A01 and A03 from the hospital EMR.
Acknowledgement Message
Acknowledgement messages are short messages that a receiving system sends back to the sender to confirm that the message was received. This is on top of packet level acknowledgement we discussed earlier. Now we are talking about application level acknowledgement. Whether a complete, fully assembled message was received or not.
Message acknowledgement is very important in HL7. We don’t want a situation where messages are getting corrupted or lost on the way and the sending system has no clue. If there was an issue with the message then it’s the acknowledgement message that conveys the information back to the sender. This way the sender knows how to fix the issue and resend the message. If there was no acknowledgement at all then that means the message was lost and its time to resend it.
It is important to know that HL7 requires acknowledgement from the application and not just the underlying system. This is to ensure that the message was successfully processed by the receiving application. The Ikea in the HL7 world just doesn’t want to know whether you received the parcel, it wants to know whether you were able to assemble the furniture.
There are two kinds of acknowledgement messages in HL7: original & enhanced. As you can guess, original came before enhanced but the original acknowledgement is nowhere close to being discarded. The original mode of acknowledgement is still the preferred method. It is simple and does the job whereas the enhanced mode has too many bells and whistles and takes a lot more effort to implement.
Original mode is formally known as Accept Acknowledgement. Once a message is received by the destination system, it can send back three types of codes. The codes tell you what happened to the original message.
AA: This is good news. It means the message was successfully processed by the receiving system. It is also commonly referred to as a positive ack or just ACK.
AE: This means the message was processed but there was a problem in the content of the message. This is a negative ack or a NAK.
AR: This means there was a processing error. It could be a wrong message type or some other problem with the receiving system. Maybe the server was down or the database was not available. This error doesn’t have anything to do with the content of the message. It too is known as negative ack or a NAK.
Enhanced mode is formally known as Application Acknowledgement. In this case, there could be up to six different types of codes. Using the Ikea example again, in enhanced mode, Ikea will get two acknowledgements. The first acknowledgement is sent when the parcel is received at the destination, and the second is sent after the furniture is assembled (or not).
The first acknowledgement, confirming that the message was received and safely stored by the receiving system, frees up the sending s
ystem from having to wait and see if the message needs to be resent.
The first acknowledgement could generate three types of codes:
CA: Commit Accept: This means the message was accepted and safely stored by the receiving system.
CR: Commit Reject: This means the message was rejected and not stored by the receiving system. Maybe the message type was wrong or there was some other problem with the message. An error code is included to provide more information.
CE: Commit Error: This again means the message was rejected and not stored. In this case the message was rejected because of meta-data issues.
After successful storage, the message is made available to the application and then a second acknowledgement is sent. This acknowledgement is more elaborate where the acknowledgement message structure depends on the message type of the original message and it contains a lot more information than the original mode.
The second acknowledgement message generates the same three error codes, AA, AE and AR that are generated in the original mode. Enhanced mode is like the original mode with an additional acknowledgement for safe storage of message by the receiving system.
6. Message Building Blocks
To the uninitiated, the sight of an HL7 message is often intimidating. A brew of symbols and characters, it looks like something out of the Matrix that is beyond the comprehension of mere mortals. But to be honest, HL7 really is quiet simple and straightforward, once you know how to read it. And for that, you will need to learn about the building blocks of an HL7 message.