Thursday, March 31, 2011

Red Wings Playoff Prospects

The Red Wings lost another home game last night. Badly.

They lost to the St. Louis Blues. The final score was 10-3. I saw some of the first period. I played hockey last night, so I missed most of the debacle.

This team is not very good. They remind me of the teams from several years ago that won a lot of regular season games, but suffered early playoff exits.

Their defense is horrible, and the goaltending is questionable. That's not the sort of team that does well in the Stanley Cup Playoffs.

They seem to think that they will wake up one day in the playoffs and will magically be able to "switch on" and eliminate all of their bad habits and tendencies and have a long run in the playoffs. I fear that they will run into a team that is playing well, has been playing "playoff hockey" for the last month or so just to make the playoffs, has a hot goaltender, and the Wings will lose in five or six games.

Time will tell.

Tuesday, March 29, 2011

Processing 997 Files. Using an Interface Engine for Process Improvement

I've recently been working on parsing X12 files. My former colleagues referred to these files as "EDI" files, which is kind of silly. There may have been only a single format for the electronic interchange of data once upon a time, but in 2011 there are lots of ways to exchange data.

I worked on x12 848 transaction set (Materials) messages about fifteen years ago. I was part of a team that developed an implementation guide for the exchange of Material Safety Data Sheets (MSDS) between Tier 1 Paint Suppliers and Auto Manufacturers.

This project is much simpler. We receive an x12 997 Acknowledgement file from one of our trading partners. We send charges to them and they submit those charges on our behalf. The 997 file tells us whether the claim has been accepted by the payer.

For as long as anyone can remember, our operators have been receiving these 997 files and then manually looking through them to determine if the claim was accepted.

This is what an inbound 997 file looks like:

ISA*00* *00* *ZZ*562402607 *ZZ*383386347 *100312*0639*U*00401*000002331*0*P*:~GS*FA*562402607*383386347*20100312*06394602*2331*X*004010X098A1~ST*997*2331001~AK1*HC*275615~AK2*837*999999~AK5*A~AK9*A*1*1*1~SE*6*2331001~GE*1*2331~IEA*1*000002331~

Yes, there are no carriage returns in the file. They are optional. The segment separator is the tilde ("~").

I had Rhapsody create a message definition for the 997 file and then built a route that picked the following fields from the file.

  • AK2-1 Is the Transaction Set ID (In the example message, the AK2 segment is “AK2*837*999999”, which makes AK2-1 “837”). The ack is for an 837 file.
  • AK2-2 is the Transaction Set Control ID (In the example message, the AK2 segment is “AK2*837*999999”, which makes AK2-2 “999999”). This is the ID of the transaction that is being ack’d.
  • AK5-1 is the Transaction Set Ack Code (In the example message, the AK5 segment is “AK5*A”, which makes AK5-1 “A”). The transaction set is acknowledged.
  • AK9-1 is the Functional Group Ack Code (In the example message, the AK9 segment is “AK9*A”, which makes AK9-1 “A”). The functional group is acknowledged.

I then had the route build an email message using javascript that I send out using the email communication point in Rhapsody.

The script looks at the ack codes and sets text so that I don't have to remember what "R" means. That code looks like this:

if (TSackCode == "A") {
TSackMessage = "Accepted";
if (TSackCode == "E") {
TSackMessage = "Accepted, but errors were noted";
if (TSackCode == "R") {
TSackMessage = "Rejected";

There is similar code for the Functional Group Ack Code.

The email that gets built looks like this:

subject: X12 997 File Received from xxx: Accepted

Rhapsody received 997 Functional Ack Message from xxx for 837 - 999999
Transaction Set Acknowledgement Code is A: Accepted
Functional Group Acknowledgment Code is A: Accepted

The operators will still have the file to look at, should they wish to. We can get the computer to parse the message and send the results in an email. This email should make their job just a little bit easier, and, after all, don't computers exist to make our lives easier?

Monday, March 28, 2011

What is a Null Flavor and How is it Used?

I wrote this for the ONC CDA IG Consolidation project. Well, actually Keith Boone rewrote the first paragraph.

IT solutions are designed to store and manage data, but sometime we do not have the data for various reasons. Typically, in these cases, a special value, known as NULL is stored. There may be several reasons why the data isn’t available. In some cases, it may not be available or known, in others, it is not relevant, and in others it may not be computable or measurable. In HL7, these different reasons for why the data isn’t available are described as the flavor of NULL. This supports the management of the missing data. Let’s look an example.

If a patient arrives at an Emergency Department unconscious and with no identification, the system would represent the lack of information by use of a null flavor. The patient’s birth date would be unknown and would be represented using a null flavor. In this case, the appropriate null flavor would be “NAV” which is the code for “temporarily unavailable”. This information is not available, but is expected to be available later. In this example, when the patient regains consciousness or a relative arrives in the ER, we expect to know the patient’s birth date.

<birthTime nullFlavor=”NAV”/> /* coding an unknown birthdate */

Here is another example of using a null flavor for a patient who does not have a home phone.

<telecom nullFlavor=”NI” use="HP"/> /* coding a patient who does not have a home phone */

For those constraints that require the presence of an attribute that is unknown (SHALL be present with a cardinality of at least one (1..)), use a null flavor.

  • NI = No Information. This is the most general and default null flavor.
  • NA = Not Applicable. Known to have no proper value (e.g., last menstrual period for a male).
  • UNK = Unknown. A proper value is applicable, but is not known.
  • ASKU = asked, but not known. Information was sought, but not found (e.g., the patient was asked but did not know).
  • NAV = temporarily unavailable. The information is not available, but is expected to be available later.
  • NASK = Not Asked. The patient was not asked.

There are a handful of other codes. See the null flavor vocabulary table for the complete list.

A Document Interface

One of our trading partners is sending us clinical documents from their EHR system. These are plain text documents. The documents are being sent in HL7 v2.3 ORU^R01 messages.

They are sending us the document in a single OBX segment with line breaks in the OBX-5 field. I have seen other systems send each line in a separate OBX segment. I call that the "card punch" format, because each line of the report is on its own data card, just like the old days.

This is what one of the messages looks like:

OBR|1||999999999|PROGN^Progress Note^^^xxx SICU Progress Note|||...
OBX|1|TX|PROGN^Progress Note||...NOTE GOES HERE~New Line~Another New Line||||||F|||20110328082242||

They are sending us the following document types (the left value is the code that I recieve, and the right side is the corresponding LOINC code):

DISCH^Discharge Summary ==> code="18842-5" displayName="DISCHARGE SUMMARIZATION NOTE"
PROGN^Progress Note ==> code="11506-3" displayName="Subsequent evaluation note"
HP^History and Physical ==> code="34117-2" displayName="History and Physical Note"
CONS^Consultation ==> code="11488-4" displayName="CONSULTATION NOTE"
OPRPT^Operative Report ==> code="11504-8" displayName="Surgical operation note"
ADMN^Admission Note ==> code="34862-9" displayName="Admission Evaluation Note"

The document type code appears in the OBR-4 field and the OBX-3 field. The project manager has me filtering out the H&P documents because they are not in scope for the first phase of the project. I added a filter to discard the H&P documents, and I will get to remove that later.

The only other interesting thing is that I have to look up the National Provider Identifier (NPI) for the providers in the PV1 segment. The remote system is sending us their provider ID, and we need the NPI to match on. So, I have a database look-up that retrieves the NPI and places that in the message. I am performing the look-up on the PV1-7 Attending Doctor, PV1-8 Referring Doctor and the PV1-9 Consulting Doctor fields. I then take whichever of these three fields has an NPI (and is therefore, one of our doctors) and place that value into PV1-7.

NextGen will match on PV1-7 and will place the document into the doctor's PAQ (Provider Approval Queue). The document was already signed by a doctor at the sending facility (unless it is a Progress Note, in which case it may be signed by a non-doctor), so our Doctor's are not really "approving" the document. This is just a way to ensure that our doctor's see the document.

NextGen will also add the document to the appropriate patient's chart.

We are doing some final testing on this interface before moving it into production.

Tuesday, March 22, 2011

PHI, HIPAA and Why Patients Should Worry

Sometimes, I despair.

People are worried that when we put their health information into EHR systems, it will be vulnerable to hackers. They worry that anybody will be able to see their medical records. The large hospital systems that I work with are fairly well protected. Their security personnel are well trained professionals who take their jobs seriously. They ensure that technical controls and process controls are in place to secure their systems and the data that is contained in them.

But a system is only as secure as its weakest link.

Today, I got an email asking me to set up an interface with an external trading partner. It's a simple, file based interface. I just need to go out to an external ftp site, pick up a file and deliver a copy to an internal system for them to process.

I told the Project Manager that if the file contained Protected Health Information (PHI) we would need to use sftp instead of ftp for the transfer to protect the information.

He asked me what data elements would be considered PHI.

This is a project manager at a medical school. We learn what PHI is and why it needs to be protected whenever we take HIPAA refresher training.

I gave him a short list and sent him a link to a faq.

The file that they are proposing to send contains names, addresses and phone numbers of patients. It is most definitely PHI, and I will not build an interface that does not protect it adequately when it is flowing over the wire.

If I had not asked, this data would have been transmitted in the clear, over the wire and been vulnerable to interception.

The level of competence found in IT staff at smaller provider organizations concerns me. That's where we are vulnerable. Hackers will not waste their time attacking the well defended, hard targets. They will steal your data from the poorly defended, soft targets. I fear that there are too many easy targets out there.