Why Healthcare Experience is Important for Healthcare IT Types

When I was a military medic I was fond of saying, “For every 100 people in healthcare there are 50 ways of doing things…49 of them are right.”

Any experienced HL7 programmer will tell you that sometimes much of the HL7 specification can be open to interpretation.

Take for instance the term MRN.   How many of you immediately recognize it to mean “Medical Record Number”?   What does that mean in your facility?  How does your HIS associate this to the account number (visit number,encounter number, etc)?

Many people will give different answers,  and they will mostly be correct.

That’s lesson #1:   Everyone does things differently.  If you have 10 years experience working for a single healthcare organization is can be something of a shock when you step out into the wider world.

That was a hard lesson for me to get my head around when I worked for an ED Systems vendor.  My only exposure to the healthcare world was in the military.  So while I could discuss how to implement something like The Ottawa Rules for deciding when an x-ray was necessary for an ankle fracture with front line clinical users,  I was often confused when discussing identifying patients through the registration process.

A few years ago, when the Ontario government was ramping up e-health,  HL7 became a very desirable thing to have on one’s resume.   Of course, its an essential skill for an HL7 Integrator.   However, many gloss over the requirement to understand exactly how healthcare works.

Case in point….I recently implemented a new interface with an outside organization.

When I looked at their spec I was baffled.

They wanted me to add an OBX segment to ADT-A01 messages.   In this segment,  they wanted me to add the hospital contact information.   At the same time, they gave me a code table so I could put the proper hospital code in the sending facility field in the MSH segment.

To those who don’t have a background in HL7 let me explain…an OBX segment usually contains the results of tests.  It is found in ORU messages (Observation Results).   ADT (Admission, Discharge and Transfer) don’t typically (as in ever) have OBX segments, because there are no results to report on.

So, this is like ordering a burger at a restaurant….. when it arrives,  you see that in place of a hamburger (or chicken, or tofu..) patty, there is a big slice of cherry pie….yes, its still edible,  but its just wrong on so many levels!

For the record,  I flat out refused to do this,  pointing out that the hospital information should be pulled from their database, at their presentation/application level.

I next looked at the messages they wanted…  Admit,  Cancel Admit, and Discharge messages.    They would match on the HCN as their Primary Key.

I sent them an email and pointed out that as they were looking for ER visits,  that quite often we do not have the patient’s HCN when they arrive,  and that sometimes we don’t even know who the patient is.    I followed up by pointing out that without accepting update messages,  that they would be getting bad data.

They responded by telling me that if I didn’t send an HCN in the A01  they would match on name, gender and date of birth.

There are at least three patients in our MPI who match on those three fields….

They seemed baffled by the fact that that could happen.

I also pointed out two things that should be obvious to anyone with enough experience in this field:

1)  A person could be identified in my system as Smith, Jim A,   and in their system he could be Smith, James Arnold,  and

2)  Sometimes Registration Clerks make mistakes….

They pointed out that previous sites they implemented with would store their messages and forward them once a day.   Translation “We built a bad interface, and made hospitals do extra work to make up for that.”.    I refused to do that,  because of the amount of work involved,  and the additional failure points.

They decided to proceed anyway…telling me that they still didn’t want Update messages because they wanted to avoid a “chatty interface”,  and “it would mean more work”.

The lack of experience,  and inability to take responsibility and fix a bad design means that this entity will be receiving bad data.    Its not a patient safety issue,  or I would’ve refused to implement it.

The fact that other organizations worked around The Bad means that those that designed this system (they have HL7 in their job titles)  will go on to other projects.   The Bad will continue….and eventually they might end up designing a mission critical system where a failure could result in a poor patient outcome.

Leave a comment

Filed under General Information

Sticking to standards for fun and profit (or just saving money…on integration programming…and Aspirin)

I remember when leaving the military in 2000,  hearing about all these high paying tech sector jobs in IT and how almost every community college had a special program that would take your average person who was baffled by their microwave and turn them into tech savvy IT gurus.

The end result was IT certificates and diplomas became next to worthless, because all it meant was that you could spout off IT terminology and theory like you knew what you’re talking about,  but have no idea how to actually apply this knowledge in a real world environment.  (I suspect many of these people become consultants to tv and movie writers )

Sadly, there is evidence that this is becoming more and more pervasive in the healthcare IT world.  While I’m addressing integration, I suspect its likely in all aspects.

In our public healthcare system we are often called upon to implement interfaces for a variety of purposes in various jurisdictional realms.

I once ran across a job posting for a “Senior Healthcare Integration Architect” for one of these jurisdictional bodies.   I was horrified (quite literally) to see that required knowledge list was extensive and contained a lot of things that I, an experienced and seasoned integration programmer,  had to look up,    but  listed as “desirable” (as in, its okay if you don’ t have this) were  HL7 integration, and  experience in a healthcare environment!

Those were optional….for a position with  “Healthcare” and “Integration” in the job title!

Therein lies the problem.   The belief that all systems are the same,  whether its transport logistics,   travel booking,   education,   healthcare…a system is a system is a system….right?   Yeah…NO!

So what happens is that someone with no idea on how hospitals or other healthcare entities operate gets into a position like that,  is told to design an interface,   does so,  using what he or she views as the “latest and greatest” of technologies.    This gets foisted on the reporting facilities who don’t have the expertise on staff (because you know….HL7 is the healthcare standard),   who then have to go out and find a vendor to design and maintain the interface.   Of course vendors don’t do things for free…so healthcare dollars that could have gone to patient care,  ends up going to some programmer,  working for some vendor.    All because some one didn’t think it was important to hire an Integration Architect who had any real experience in healthcare.

If everyone across these jurisdictional silos adopted a single standard (*cough*HL7*cough*),   either hired people with the understanding of how healthcare works,  or even consulted the workers in the trenches  the cost savings would be tangible.     Implementation time for projects would be reduced,  as would ongoing support costs and headaches.

The practice of hiring senior people from outside the industry,   who impose technical requirements that are so far out of the realm of the everyday hospital IT department is doing a disservice to those who provide healthcare services.

A case in point is the SPIRE project which was implemented in LHIN (Local Health Integration Network) 1 and 2 in Ontario.    This was a project that was set up to provide local doctor’s offices with lab and other reports on their patients electronically, in real time.

After several attempts to come up with an HL7 specification by other parties,   a meeting was held,  inviting the integration programmers for the hospitals involved.   We spent an afternoon cloistered in a conference room where we went through the HL7 standard specification,  field by field and hammered out a specification that could be met by any of the different Hospital Information Systems involved.

The result was an elegant, easy to implement solution.   No hiring outside vendors,  or struggling with Web Service connections.   A simple HL7 interface over MLLP through a tunnel,  or SFTP.

This should be the standard practice when implementing a new project.

HL7 isn’t new,  it isn’t cool,  it isn’t sexy…..but it works.   HL7 interfaces typically have very low overhead,  aren’t resource intensive and are extremely robust  (and almost every hospital has their own HL7 engine).

So why isn’t it universally implemented in healthcare?



Filed under General Integration

Adding an escaped linebreak in Javascript

If your working in Javascripting what happens when you try to add a line break like \br\ to your code?

Most parsers will choke on it as the backslash is also used as a string terminator.

Here’s how I did it:

var linebreak = String.fromCharCode(92) + ‘.br’ + String.fromCharCode(92);
if (seg[‘OBX.5’][‘OBX.5.1’].toString() == ”) {

    seg[‘OBX.5’][‘OBX.5.1’] = linebreak;


Fairly clean solution.


Leave a comment

Filed under Mirth Integration Engine, Tips and Tricks

Entity Relationships in Healthcare

While you’d think this would be quite simple,  from an programmer’s standpoint, one of the most confusing things in modern healthcare is how a patient’s record is managed.

The patient comes in,  is seen,  documented on and said documents are then associated to the patient.    Fairly simply right?   Once you start factoring in statistics and billing it gets much more complicated.   There are different types of visits that all must be handled different ways, and different facilities all have different ways of doing things.

What does this mean to the HL7 programmer?   If you’ve read this article, you’ll recall I talked about the differences in how facilities manage patient flow, and even the terminology they use can be different.   This can be daunting to a programmer with little experience in healthcare and can cause problems if systems lack the right combination of HL7 compliance and  flexibility to accommodate the myriad of configurations found in the real world.

One of the most frequent issues I’ve seen with healthcare systems,  especially integration is when they were designed by someone who does not understand how many different ways things can be done in the healthcare world.

Every integration programmer needs to understand the basic concept on how different parts of the electronic record fit together.   Most information systems organize data using a relational database model.   By that I mean that information is stored in different tables and not giant flat files.   It is essential that anyone designing systems for use in healthcare settings understand the differences between a patient and a patient visit,   between an order and a result,  and how different parts of the record tie together.   In order to gain this understanding one must have a firm grasp on how the relationship types 1 to 1 and 1 to many work and where they apply within a patient’s record.

An example of a 1 to 1 relationship might be patient visit to demographics,  but only if the patient doesn’t move residences during their stay.   One might say that patient visit to insurance might be a 1 to 1 but even in Canada where we have a single payor system a patient can have several insurance plans associated with a single visit.

While it should be obvious that a patient to patient visit relationship would be one to many as a single patient can present many times,  a not so obvious example is an order for tests would have a one to many relationship with the results.     The reason for this is that the order could comprise not only of different elements that need to be reported separately but there could be preliminary results,  final results and amended results.

Now that we have an idea on how some of these different tables tie together, now we talk how to identify different entities within the patient record.   The easiest way to break this down is to present the information in a table.

Properly formed HL7 messages will always contain a PID segment identifying the patient (unless of course there is no patient associated with the data).     This allows the receiving system to properly associate the incoming data with the correct patient and visit.

There are three types of matching when it comes to matching data to a particular record.   Person Match, Account Match and Accession Match.

A person is identified by an individual unique record within the Master Patient Index.    A Person Match will associate the data with the medical record belonging to a particular patient without matching it to a particular visit.   If you are updating a patient’s address or some other piece of demographic data this would be done using a Person Match.

An Account Match,  a.k.a  Visit Match,  or Encounter Match will match the data to a particular patient visit to your facility.  If a patient is admitted to your facility,  the patient’s location, admission and discharge times would all be associated to the account.   In a properly normalized database structure,  the system will know which person the visit is associated to automatically.

An Accession Match is where results are tied to a particular order.   If a physician orders a battery of tests called an “Order Set”  the typical Lab Information System will assign all the components of the order set to a particular unique accession or order number.    This number will be associated to a visit number,  which is then associated to a person.  All results sent via HL7 will be linked to this order by way of accession number.

All that is pretty straight forward but there are some pitfalls that may be encountered.  Take insurance information.   On the face of it you may consider insurance information be associated with the person,  however,  when you consider further you’d know that insurance also must be associated to the visit.   Insurance can change,  there fore if you have a change in insurance between visits you’d want insurance company A associated with visit A and company B with visit B.    Some system will also associate new insurance levels to the person,    to be recalled automatically when the person returns.

As you can see healthcare records maintenance is a complex thing.    Healthcare systems designers and programmers simply must have a solid understanding of how information fits together and be able to design their systems with the flexibility and scalability to accommodate the myriad of different methods existing today.

1 Comment

Filed under General Integration

Queue Alerts in Mirth

I have several channels where its important to know if queues are starting to build so that I can notify users and call the administrator of the receiving system.

In this particular case the email will go to myself,  2 colleagues in the IT department and the PACS Administrator as she needs to notify users.

The complicating factor here, and why I don’t use Mirth’s native alerting system is that we occasionally get more than 100 messages in queue.  I don’t want to generate an alert email for every message so I have some code that will only send out an alert every 3 hours.

To do this,  I have this code in my channel’s deploy script

var newtime = new Date(“January 1 1990”);        //This resets the ‘last alert’ variable ensuring the alert will fire if the alarm condition occurs shortly after deploying

globalMap.put(channelId + ‘_lastalert’,newtime);

In the post-processor script I put this code:

/Check to see if the alert has already been sent within the given timeframe
var lastsent = globalMap.get(channelId + ‘_lastalert’);            //last time an alert was sent
var rightnow = new Date();                                        //Current Datetime
var hLimit = 3;                                                    //Number of hours before resending an alert

var datediff = (rightnow – lastsent) / (1000 * 60 * 60);        //calculates hours since last alert went out

if (datediff < hLimit) {


} else {

//This is the bit that does the heavy lifting

var controller = Packages.com.mirth.connect.server.controllers.ChannelStatisticsController.getInstance();
var channelName = Packages.com.mirth.connect.server.controllers.ChannelController.getInstance().getDeployedChannelById(channelId).getName();
var stats = controller.getStatistics(channelId);

//I include all these so you can see what’s available
var mSent = stats.getSent();
var mReceived = stats.getReceived();
var mQueued = stats.getQueued();
var mError = stats.getError();

var qAlarm = 20;                                                  //This is the limit of queued messages prior to triggering the alert

if (mQueued >= qAlarm) {

var emTo = ‘somone@email.com’;                                      //This is the email address you want to send the alert to.  Multiple emails can be separated with a comma
var emCC = ”;                                                      //This is any cc emails you want to include
var emFrom = ”;                                                  //This is the “From” address that will appear on your email
var emSubj = ‘Queue Alert for Channel: ‘ + channelName;              //This is the subject of the email
var emBody = ‘Queued messages detected on channel ‘ + channelName + ‘.\n’;
emBody = emBody + ‘Current number of queued messages is ‘ + mQueued.toString() + ‘.\n’;
emBody = emBody + ‘This alert will not be resent for ‘ + hLimit.toString() + ‘ hours.\nPlease do not respond to this email. This address is not monitored.’;

var smtpConn = SMTPConnectionFactory.createSMTPConnection();    //Opens email connection using email settings in your Mirth Connect Settings.


globalMap.put(channelId + ‘_lastalert’,rightnow);


The code is portable, meaning that it will work in whatever channel you put it in.  I have these stored as code in my global templates so I can just click and drag it over.

Remember to edit the To, CC and From variables (lines 31 to 33) in the post processor and to have an SMTP server set up in your Mirth Connect settings.

I’m currently working on a channel that will email the user the current statistics on the channel if they reply to the alert email.  You will need the Email Receiver that comes with Mirth Support packages


Filed under Mirth Integration Engine, Tips and Tricks

Using HL7 for more than just Integration

When I first started in medical integration I realized that when our vendor quoted us for a new integration suite that an HL7 ADT feed was included each and every time.   I thought that was odd as this same vendor had already provided us with two individual ADT streams (one in V2.2,  and the other in V2.4).   When I asked it was explained that each receiving system required its own ADT feed.   Naturally this is the case when dealing with several different systems,  but modern Integration Engines eliminate the need for redundant feeds from your HIS (Hospital Information System),  or EHR (Electronic Health Record).
Over the years whenever we implemented a project that required an ADT feed we used our Mirth Integration Engine to send a copy of an existing feed to the new interface.   Mirth allows us to do any customization or filtering for each system so in the end we save ourselves tons of money in purchasing and maintaining seperate ADT feeds from our HIS.

This is a pretty simple example of what I want to talk about in this entry.  With the right Integration Engine,  and enough data in your HL7 message you can easily use existing feeds as a unique and robust solution to day to day issues that come up.   Here are some of the things we’ve done at the Huron Perth Healthcare Alliance.

Enhanced Data Analysis and Reporting
At one point we were having a problem with guarantors not being properly associated in our HIS.   This was causing our analysts fits as they would have to spend hours trying to track down potential mis-matches.
Mirth’s versatility and powerful javascripting abilities allowed us to implement an interface that would watch our main ADT feed and an analysis on every message.   Business rules were drawn up to identify a potential mis-match and,  if a message met those parameters the patient details would be written into a database.     Every night just after midnight,  another Mirth channel would trigger,   read the database and email the analyst a list of potential problem accounts  reducing workload and catching potential problems before they became problems.
This functionality can be easily adapated to watch for any records meeting certain business rules.

Custom Data Repository
We needed a way for several applications (including Mirth) to be able to pull certain information from our HIS.   The problem is that our HIS doesn’t allow direct queries.   We were faced with writing a script to pull this information periodically,  thereby limiting our ability to pull real time data and adding a level of complexity to the solution,   or,  we could write everything to a database and use SQL to pull the information.
Again,  we used existing HL7 feeds from our HIS to populate and update a lighweight data repository.   This gave us real-time information in an easy to query format simplifying our reporting tasks and allowing us to provide better data to the users.

Downtime Reporting
Anyone working in healthcare has come to dread what happens when the HIS is unavailable for any reason.  Of course,  in an electronic environment this means that vital patient info is not available.
Again,  using the Mirth Integration Engine and an existing HL7 results feed that gives us every test result and dictated note entered into the system we devised a solution.   Every report is converted into a human readable PDF.   This PDF is then picked up by another Mirth channel which determines what nursing unit the patient report belongs to and will write it o a folder on a PC on that floor.   This way the patient information is available to staff on the floor in the event of an HIS or network downtime.
Phase 2 of this project will involve moving patient records to another floor upon receipt of a patient transfer message,  or removing them if a patient discharge message is received.

These are just a few of the many functions a powerful integration engine such as Mirth will allow facilities to enhance the utility of HL7 messages coming from their systems.

Leave a comment

Filed under General Integration, Tips and Tricks

HL7: A Programmer’s Viewpoint

HL7 or “Health Level 7” is the accepted messaging standard for medical systems interoperability.  To put more simply,  HL7 is the language that medical systems use to speak to one another.  There are many references out there that talk about HL7, versions and standards.   This article will discuss things that affect programmers and integration specialists.

One of the greatest and worst things about HL7 is agility.   HL7 allows a programmer almost an unlimited number of options when designing how something will mesh with other systems.  On the face of it that’s a great thing!   The big problem with this agility is that some designers either choose not to use it, or design their system based on limited exposure to the healthcare world and end up hobbling their system’s ability to integrate.

Anyone who has worked in medical systems integration for a length of time will be aware that “HL7 compliant”  can mean many,  many things.  The reason for this is quite simple.  As a military medic I learned that  for every 100 people in the medical profession there are 50 ways to do something and that 49 of them are right.  Its important

As an example lets look at patient flow through the ER.  Most Canadian ER’s the patient’s physical flow starts at triage, they are then registered,  then treated.

Pretty simple eh?

Depending on the facility the HL7 flow can be very different.  For instance,  at my facility an A05 Pre-Registration message is generated when the patient is triaged.   This message contains a different account/visit number (PID.18)  than the patient will receive when the A04 Admit message is generated at registration.   Other facilities use an A01,   yet others use an A08 updating the original Pre-Registration account.  There are many reasons for doing this,   the only thing the HL7 Programmer needs to worry about is the ability to accommodate whatever workflow is in place.

You may have noticed that  “account/visit number” was mentioned. This is one of the other things people need to be aware of when dealing with different systems,  differences in terminology.  I’ve seen the number appearing in PID.18 be referred to as  Account, Visit, and Encounter number.  Meanwhile in PID.3  I’ve seen values there referred to as MRN or Medical Record Number,   Patient ID,  Patient Number.   In our facility we call them “H Numbers” as they all start with H.
For those of you who aren’t familiar the figure in PID.18 is associated with a single patient visit to the hospital.   In other words,  it will change each time the patient presents to the facility.   The figure in PID.3  will remain the same. so it will have a one to many relationship with PID.18.

Another pitfall in the medical integration world,  and, in my opinion,  the most maddening,  is when a system is designed with no real recognition of the HL7 standard.   For some reason some programmers feel no need to follow accepted practice and instead do things their own way causing headaches for other programmers who work on their project.   I was coding for one system the other day that,  instead of leaving the Alias in PID.9,   I had to reformat it, and concatenate it to PID.5.    The explanation for this was to accommodate more than 2 alias’.    I’ve no idea why this would be important as the most current name (and alias) come across in the message.   You’d think their system would just write into the patient’s record what name the patient used for that account.

Personally, if I absolutely needed the ability to deal with the possibility of an infinite number of alias’ I would’ve created a Z segment.    Easier to code,  and much cleaner looking.   Any segment starting with “Z” is a custom segment and would consist of 2 additional letters.  Of course,  in saying that I’m presuming that every system using the interface into which I would use Z segments for alias’ allowed the flexibility to accommodate the arbitrary addition of  segments,  custom or otherwise.   Its an easy trap to fall into.

As a programmer in the medical integration world its important to remember that while HL7 is a standard,   its definition and implementation are open to interpretation.   A well designed,  robust  HL7 Integration architecture means that its very close to the standard,  but has the flexibility to accommodate interfaces that aren’t so well designed.

After all HL7 is the standard,   all we have to do now is standardize how its interpreted!  A task which would be akin to herding cats.

This brings me to the subject of Integration Engines.    There are some big names in the integration game,  Mirth,  Iguana,  Cloverleaf,  Biz Talk,  MDILink  to name but a few.

I only have experience with Mirth and Biz Talk  however I did receive a demo of Iguana from Interfaceware’s Eliot Muir that blew my mind.  If you get a chance check out Iguana at their website.  Their IDE should set the standard for IDE’s globally!  (I didn’t get paid for saying that either, I’m that impressed).   Hopefully one day I’ll find some time to play with Iguana and will write about some of its features.

A good integration engine will give the programmer the ability to do pretty much anything they need to with a message of any type.   It should also be able to accommodate a broad range of connection methods in order to ensure that the user is not hindered in their ability to accommodate the needs of the various systems that are out there today.   In my opinion IE’s  should also use a common programming language and not force users to learn a propietary language.

Other things that you should look for when shopping for an integration engine are:

  • Its abilities to respond to failures.
  • How robust and flexible are its alert  features?
  • Is the UI and navigation intuitive?
  • What is support,  both professional and community like?

In the interest of fairness and full disclosure I will point out that we use Mirth, an open source integration engine at the Huron Perth Healthcare Alliance.   I am a big supporter of the Mirth community,  you will find me on the forums here MirthCorp website as “Bostad”,   as well as on the community IRC channel.

Trying to find a single,  globally accepted interpretation of the HL7 standard is a lot like trying to find images in clouds,   just as you find one the wind will pick up and it will drift away.   Having the understanding,  and the right integration engine makes the wind irrelevant,  as you can shape that cloud into whatever you need.

1 Comment

Filed under General Integration