Tuesday, July 28, 2015

Patient Identity Matching without a National Identifier in IHE Profiles

In the US, because Congress won't even let anyone in the Federal government TALK about creating a national identifier (privacy concerns), we have to deal with multiple identifiers at every healthcare provider.  At least in Canada, the provinces can assign a provincial patient ID.  But, not here alas.

So, last week at the IHE Meeting, somebody asked what identifiers are supported in IHE Profiles, from this list.  I think this query may have been in support of this project.

First Name
Last Name
Middle Initial
Suffix
Date of Birth
Gender
Race
Home phone number     
Address
·         Street
·         State
·         Zip
Middle Name
Cell phone
Mothers Maiden Name
Prefix
Marital Status
Alias or Previous name     
USPS Address
Identifier:
·         Last 4 of SSN
·         Driver License
·         Passport
·         Alien #
Multi Birth
Birth Order
Birth Place
E-mail
Previous Address
Previous Cell Phone(s)
Insurance ID
Insurance Plan Name
Previous Insurance
Medicaid ID
Medicare ID
Biometric ID

So, I put together a spreadsheet mapping these identifiers to HL7 V2.5.1, PIX, PDQ, PAM, PIX/PDQ V3, XCPD, and PDQm.  It didn't take too long, just a couple of hours.

A quick summary: HL7 Version 2 and PAM supports all of these directly by name with the exception of the alien #, which is simply another identifier in Patient Identifier List (PID-3).  HL7 makes no distinction between current and previous at the field level, although other parameters can be used to distinguish a current address from a previous address, or a current insurance identifier from a previous one. The notion of previous is dependent upon the time the query is performed, rather than being an attribute of any of this data in any case.  The distinction between Alias and simply another name is slim enough that even though PAM doesn't support the alias field, you can use repetitions of the name field to get there.

I don't think race belongs in this list.  It's not an "identifier", because in the US, race is whatever the patient says it is at the time that they say it (see OMB Policy Directive #15), and shouldn't be completed by someone else.

PDQ in all its flavors (V2, V3, and Mobile/FHIR) supports most of these (in bold).  Some (in italics) require the use of the Pediatric Demographics Option.  XCPD is a super set of PDQ V3, so it too supports the same set.

PIX (in all its flavors) performs patient matching.  IHE doesn't specify the algorithm, because master patient directory systems use a variety of different matching algorithms, and these are often tuned to the location where they are used.  Tuning parameters for name matching in Arizona could differ greatly from those in Wisconsin or New York for example.

Any missing pieces could be added as national extensions to existing IHE profiles.




Monday, July 27, 2015

Argue your limitations and they are yours

I'm having a [amusing | interesting | disheartening | great ] discussion over on Facebook with two Massachusetts doctors who are telling me how difficult it is to get information about the cost of treatment from payers.

Fortunately for me, unfortunately for them, MA state law effective January 1, 2014 states:
§228(a): Prior to an admission, procedure or service and upon request by a patient or prospective patient, a health care provider shall, within 2 working days, disclose the allowed amount or charge of the admission, procedure or service, including the amount for any facility fees required; provided, however, that if a health care provider is unable to quote a specific amount in advance due to the health care provider’s inability to predict the specific treatment or diagnostic code, the health care provider shall disclose the estimated maximum allowed amount or charge for a proposed admission, procedure or service, including the amount for any facility fees required.
(b) If a patient or prospective patient is covered by a health plan, a health care provider who participates as a network provider shall, upon request of a patient or prospective patient, provide, based on the information available to the provider at the time of the request, sufficient information regarding the proposed admission, procedure or service for the patient or prospective patient to use the applicable toll-free telephone number and website of the health plan established to disclose out-of-pocket costs, under section 23 of chapter 176O. A health care provider may assist a patient or prospective patient in using the health plan’s toll-free number and website.
Unfortunately for me, they probably still don't have a clue how to do this if the discussion I'm hearing is any clue.  This information is "difficult", hard to find, not complete, et cetera.

As my wife likes to tell me routinely, arguing for your limitations simply makes them stick, rather than producing any real change.

When I have a real health concern where this becomes an issue, I think I'll go tilt at that windmill for a while.

   Keith

Wednesday, July 22, 2015

IHE PCC FHIR-based Profiles for Trial Implementation

It's only Wednesday and already we have approved three IHE profiles to move forward into Trial Implementation, AND have the content updated for publication.  The CMAP and GAO profiles a number of comments from IHE and HL7 participants.  GAO received 50 comments.  CMAP received 30.

These profiles, like just about anything else I've done with FHIR were very easy to update.  We are usually scrambling to get this work done by the end of the meeting (tomorrow), and often have to complete our editing in the following weeks.  By this morning, we had already finished two of these, and after about 90 minutes of editing during lunch, I had finished GAO, which was the more complex of these two.

You can find the prepublication copy of these profiles on the IHE Web site.  They await a final editorial pass starting next week, and will be published very shortly.

I now have one work item left on my plate for THIS meeting, which is to finish up the BPMN white paper for public comment.  That's going to take some major editorial work, because it is as much an instructional guide to creating an IHE XDW profile in BPMN as it is anything else.  That stuff is always hard to get right.

     Keith

Tuesday, July 21, 2015

I'll be back!

In my outgoing message to HL7 members as an HL7 Board Member, I made a very short, simple statement.  "I'll be back" I said.

I had made an attempt to become the HL7 Chair, and that didn't work out.  The next opportunity for that role is some time away, and I don't want to spend that much time "out of the loop" of HL7 Board governance.  So I am again running for the HL7 Board.

HL7 International Members can vote for me here.

Unfortunately, at this time, Affiliate members cannot vote for me, and that is something I'd like to change, and have been working with the Internationalization task force to help the organization move in that direction.  That's been a multi-year effort that began initially when I first joined the HL7 Board, and is making SLOW progress.  But the same could be said for the progress we made on freeing up the HL7 standards and developing new business models until suddenly one day we were actually able to announce that policy change.

Big changes like this take time and effort.  I've been part of that effort, and would like to continue to be part of it going forward in HL7.  So, please vote for me in the HL7 Election, and if not me, then at least for someone who will do a good job.  There's a really good slate of candidates this year.

   Keith

Monday, July 13, 2015

Trifolia Template Comparison for CCDA 2.1

I finished my Trifolia template comparison tool last night and used it to compare C-CDA 1.1 to C-CDA 2.1.  You can find my detailed report here. A quick summary of results follows along with some general observations:

TypeIssuesComments
Major21Most were issues where 1.1 is more restrictive (has SHALL constraints) in content that MAY be present.  It's the "X, if present, SHALL" that causes a potential problem. These constraints most often appear in performer//addr and performer//telecom.  There are also a couple of possibly missed constraints, though CCDA 1.1 doesn't always follow the same patterns with Narrative text constraints.
Minor3These were mostly cases where a deprecated template which was removed in C-CDA 2.1 might need to be addressed in a SHOULD NOT constraint, just to make the point. If folks strongly disagree, I can back down.
Future9Minor inconsistencies in constraint splitting, or where something might be fixed or clarified without changing the meaning.  These can all wait for later as maintenance as far as I'm concerned.
Total33Overall, not bad for several dozen pages of constraints.

You can get the comparison stylesheet here.  Tonight I'm probably going to compare 2.0 to 2.1 just to see what shows up.  That has a different purpose.  I want to see what it takes to create a 2.1/2.0 aware C-CDA consumer.  I think that might be a useful document to add to the C-CDA 2.1 package.



Sunday, July 12, 2015

Agile Development

I've been improving my template comparison tool over various iterations, as I have been prone to do most of my life as a software developer.  It never really occured to me that I use agile without really thinking about it in projects like these.  Since I'm both the audience, and the developer, I try something out, and see where it goes.  I start with something that minimally works, or is at least good enough to start with.  Then I look at it, and see what I want to make better or improve upon.

The tool has evolved in various stages.  I started with basic comparisons over the narrative text of the constraints.  I made some changes to remove some non-essentials from the text comparison when I first built it, e.g., conformance identifiers.  Subsequently (after implementing a few other tweaks), I realized that I could further improve that comparison by simply removing parenthetical text.

In between those tweaks, I fixed my context "bug", where I hadn't counted on the fact that that same context could be constrained in different ways.  Originally, I just iterated through all the variations, but found that two different contexts that should have lined up (entryRelationships where typeCode='COMP'] didn't, simply because of ordering issues.  So I then sorted those contexts differently, using typeCode.  I later realized that wasn't good enough, because I was comparing an entry of type Act to another of type Procedure.  So, now I look at both @typeCode and @class.

But adding typeCode and class to the context makes the output ugly, and I really don't need to see this stuff, just organize by it.  So I'll have to change my output to eliminate text between [] in my rewritten contexts.

It's still not perfect.  One of my current challenges is that while I want to keep my comparison table columns aligned between templates, I also want to support indenting of nested constraints in some way.

outer context constraint 1Old stuffNew Stuff
outer context constraint 2Old stuffNew Stuff
inner context constraint 2aOld StuffNew Stuff
inner context constraint 2bOld StuffNew Stuff

The problem is that I don't know how many rows of inner constraints will be produced until I produce the output.  So I cannot compute how many rows I need to span value for the empty cells in the inner context.

There are at least three ways I can think of to resolve this.  The simplest of these is to apply a second pass transform over the output to clean up the context breaks.  I can simply output a tag in the recursing section of the table, and then count rows and compute how to clean it up.  See there?  I've done it again.

Well, it's about bedtime (I'm in Budapest for the next three days), so I better finish up and get some sleep.

Friday, July 10, 2015

Comparing Template Versions in CCDA

One of the things that I'm doing right now is working on examples for C-CDA 2.1.  To evaluate these examples, I'm running them through both the 1.1 and 2.1 schematons produced by Trifolia, as well as a couple of other validators.  Sometimes the validators don't agree, as I've discussed previously.

To better address the compatibility issues and to verify that what I have is correct, I wanted to be able to compare requirements side by side.  So, I build an XSLT stylesheet to compare the output from Trifolia for two different template versions.  Here's how it works:

It processes an XML file containing the old XML Template in the format produced by Trifolia.  It accepts one parameter, the name of the new IG XML file (in that same format) to compare it to.  For each template in the input file, it attempts to find a matching template in the new IG, perhaps with a new version.  If there is no new version, it doesn't do anything.  If there is, it produces a table comparing the two templates.

The table displays the template metadata (IG Name, Title, Identifier, Version, Publication Status, Template Type, Open/Closed Status, Context, Previous Version, and Description).  If differences are found, the metadata name cell is highlighted in gray.

Then it traverses all the constraints within either template, sorted by context, and simply compares the narrative of each constraint, ignoring minor differences due to CONF: statement numbering in its comparison.  If a difference is found, it highlights the context cell with a background color of red, yellow or green depending on whether the original constraint was SHALL, SHOULD or MAY.

What appears below is a sample of the output.  There's still a bug or two in this, in that when two constraints apply to the same context (entryRelationship), the code doesn't correctly deal with that.  I have some work to do there yet.  When I get around to fixing that, I'll post the stylesheet.  You can see a sample of the output below.

This has proved to be very useful in comparing the CCDA 1.1 and 2.1 templates.  I wish I'd had the time to do this when we started on the compatibility work a few months back, as it would have made my life a lot easier.  However, I hadn't at that time figured out how to get a good comparison.  That's probably because I wasn't thinking about how a minimally viable comparison might work.  Now that I have that, I can actually get an even better comparison with a bit more work.

   Keith

US Realm Header

FeatureOriginalNew
IGConsolidationConsolidation V3
titleUS Realm HeaderUS Realm Header (V3)
identifier2.16.840.1.113883.10.20.22.1.12.16.840.1.113883.10.20.22.1.1
version2015-08-01:
publishStatusPublishedDraft
templateTypedocumentdocument
isOpentruetrue
contextTypeClinicalDocumentClinicalDocument
PreviousVersionUS Realm Header (V2) (urn:hl7ii:2.16.840.1.113883.10.20.22.1.1:2014-06-09)
DescriptionThis section describes constraints that apply to the header for all documents within the scope of this implementation guide. Header constraints specific to each document type are described in the appropriate document-specific section below.This template defines constraints that represent common administrative and demographic concepts for US Realm CDA documents. Further specification, such as ClinicalDocument/code, are provided in document templates that conform to this template.
ClinicalDocument/realmCodeSHALL contain exactly one [1..1] realmCode="US" (CONF:16791).SHALL contain exactly one [1..1] realmCode="US" (CONF:16791).
ClinicalDocument/typeIdSHALL contain exactly one [1..1] typeId (CONF:5361).SHALL contain exactly one [1..1] typeId (CONF:5361).
ClinicalDocument/typeId/​@rootThis typeId SHALL contain exactly one [1..1] @root="2.16.840.1.113883.1.3" (CONF:5250).This typeId SHALL contain exactly one [1..1] @root="2.16.840.1.113883.1.3" (CONF:5250).
ClinicalDocument/typeId/​@extensionThis typeId SHALL contain exactly one [1..1] @extension="POCD_HD000040" (CONF:5251).This typeId SHALL contain exactly one [1..1] @extension="POCD_HD000040" (CONF:5251).
ClinicalDocument/templateIdSHALL contain exactly one [1..1] templateId (CONF:5252) such that itSHALL contain exactly one [1..1] templateId (CONF:5252) such that it
ClinicalDocument/templateId/​@rootSHALL contain exactly one [1..1] @root="2.16.840.1.113883.10.20.22.1.1" (CONF:10036).SHALL contain exactly one [1..1] @root="2.16.840.1.113883.10.20.22.1.1" (CONF:10036).
ClinicalDocument/templateId/​@extensionSHALL contain exactly one [1..1] @extension="2015-08-01" (CONF:32503).
ClinicalDocument/idSHALL contain exactly one [1..1] id (CONF:5363).SHALL contain exactly one [1..1] id (CONF:5363).
ClinicalDocument/codeSHALL contain exactly one [1..1] code (CONF:5253).SHALL contain exactly one [1..1] code (CONF:5253).
ClinicalDocument/titleSHALL contain exactly one [1..1] title (CONF:5254).SHALL contain exactly one [1..1] title (CONF:5254).
ClinicalDocument/effectiveTimeSHALL contain exactly one [1..1] effectiveTime (CONF:5256).SHALL contain exactly one [1..1] US Realm Date and Time (DTM.US.FIELDED) (identifier: urn:oid:2.16.840.1.113883.10.20.22.5.4) (CONF:5256).
ClinicalDocument/confidentialityCodeSHALL contain exactly one [1..1] confidentialityCode, which SHOULD be selected from ValueSet HL7 BasicConfidentialityKind urn:oid:2.16.840.1.113883.1.11.16926 STATIC 2010-04-21 (CONF:5259).SHALL contain exactly one [1..1] confidentialityCode, which SHOULD be selected from ValueSet HL7 BasicConfidentialityKind urn:oid:2.16.840.1.113883.1.11.16926 STATIC (CONF:5259).