Thursday, October 27, 2016

Partial Rejection and Levels of Validity in CDA (or anything else for that matter)

One of the things that I learned in my Informatics education was that there were many different ways to evaluate validity of something.  It's not a yes/no question, but rather a multi-faceted scale.  Most informaticists are familiarity with a 5 or even 7 point scale used to evaluate quality of evidence.  This is essentially the same idea.

In a recent Structured Documents discussion, the topic of what it means to "reject" an "invalid" CDA document was discussed.  When you look at these terms, they seem like yes/no, binary decisions. But here is how you can turn this into shades of gray:

Level 0: Totally bogus content.  Is this even XML?
Level 1: The CDA Header is valid.
Level 2a: Level 1 + the narrative content is valid according to the CDA Schema
Level 2b: Level 2 + the LOINC codes for documents and sections are recognized as valid.
Level 3a: Level 2 + the entries are schema valid according to CDA.
Level 3b: Level 3a + the codes are recognized.

Here's how a system can respond after making these assessments (note that possibly available actions at higher level include those at the level below):

Level 3b: Discrete data can be imported into the system.
Level 3a: Some data can be coded based on string matching, and for that data which has matching codes, that data can be imported into the system after validation by a healthcare provider.
Level 2b: Narrative only sections (such as Reason for Visit or HPI) can be imported, but no discrete data.
Level 2a: After performing some simple pattern matching, some narrative only sections can be imported, after validation by a healthcare provider.  The document can safely be displayed to the end user.
Level 1: The CDA Header is valid.  The fact that a document has been received for a patient from a particular organization can be displayed to the end user.
Level 0: You might be able to look at some magic numbers in the data to figure out what the heck someone sent you, but there's no way to even assess what patient it was for unless you have that stored in some other metadata (thus Direct+XDM evolves as a good solution for sending files).  You might be able to figure out an appropriate viewer for the content, but even then, there are no guarantees it is safe.

Validity?  It's not a switch.  It's a dial.  And mine goes to 11.  Rejection? That's just a pre-amp filter.

Thursday, October 6, 2016

Preadopting FHIR Release Content

There are many times when you aren't quite ready to adopt a new release, either because it isn't fully baked yet (as for FHIR STU3), or you just aren't ready to suck up a whole release in a development cycle to get the ONE feature you would really like to have.

The FHIR Extension mechanism is a way that you can add new stuff to an existing FHIR release. But how should you use it for problems like those described above?

I'm going to be playing with this in the near future because I have some STU2 stuff going on right now, but I really need some of the fixes to Coverage in STU3.  Right now, STU2 talks about subscriber*, but doesn't actually link the coverage to the member (the actual patient being treated)! STU3 fixes that, and I want to preadopt the fix.

So, how am I going to handle my extensions?  Well, first of all, for every field I add, what I want to do is to name it using the STU3 (Draft) URL (and later to the STU3 URL).  So my extension URL becomes something like, and bang, I have a referenceable URL that pretty clearly defines the extension.

What does FHIR say about that?

The url SHALL be a URL, not a URN (e.g. not an OID or a UUID), and it SHALL be the canonical URL of a StructureDefinition that defines the extension.

Apparently what I've done isn't quite right because it doesn't follow the FHIR rules (even though it follows the spirit) of FHIR requirements for extensions. Right? So, NOW what?  Somehow we need to give each extension a name.

Actually, let's see what happens when I plug StructureDefinition into this equation.  I now get:  Click the link to open where that goes in a new window.  Dang!  Pretty fricken close. StructureDefinition/Coverage produces a redirect that goes to fhir/coverage.html instead of fhir/2016Sep/coverage.html.  So close.

In fact, that's nearly close enough for me.  It seems that if we were to fix the redirect problem on the HL7 Server, this would do exactly what I need.  Note: It's NOT a structure definition that defines an extension, its a structure definition that defines a resource.  But really?  Do I have to point you to a structure definition that defines it AS an extension?  Or can I just do the nearly right thing and get away with it.

I may want to adopt a resource that doesn't even exist yet.  Say I want to use some clinical decision support, but I've invested a bit already in Argonaut stuff based on STU2.  How do I handle that? Fortunately, FHIR has the Basic resource, but I'm going to need to extend the heck out of it.  No problem, I just use the same technique, with gusto, and even better, I could put some automation behind it to populate my stuff.  And so could anyone else.

I wonder what Grahame will think about this?


P.S. *  Also broken as defined in STU2, and not yet fixed in STU3 because I am not a patient at my wife's OB/Gyn practice, nor am I a patient at my children's Pediatric practice, but they clearly have me on file as some sort of RelatedPerson.  There's already a tracker for this.

Tuesday, October 4, 2016

FHIR to EHR Data Mappings

I've looked at a lot of EHR database schema over my career.  One of the things that I've found about FHIR is that it captures the essential model of an EHR system (just about ANY EHR system).  There really shouldn't be any surprises here.  It's based on six years of work that led to CCD, C32 and CCDA as well as a lot of other good information sources.  You can also find a good bit of that model already present in in CIMI via some of Intermountain's detailed clinical modeling efforts from the past.  What FHIR does differently is expose the right grain size I think, from what prior efforts in HL7 have attempted.

As both Graham and John have pointed out, yesterday's diagramming work still leaves a lot to be desired.  However, I will continue on to see where it goes.  I think there's an important piece of information there we should all be looking at very carefully.  I was already quite pleased to see that the patient and physician show up right in the center of it all.  Clustering algorithms like those used in GraphViz tend to surface interesting relationships like that.

I'm wondering if there are some better clustering algorithms to play with that might help identify interesting groupings and see how we did with resource classification.  Clearly the grouping of Individuals nailed it in Identification (under Administration).  Something like these might be worth digging into.

   -- Keith

Monday, October 3, 2016

Towards a FHIR UML Resource Relationship Diagram

One of the things that I feel is missing from FHIR documentation is a UML-like diagram of the Resources and their relationships to each other.  With over 100 resources, this is rather challenging to produce.  Fortunately, due to the data driven nature of FHIR development, the production can be automated using layout tools like GraphViz (Grahame had a love-hate relationship with GraphViz during early FHIR development, which resulted in him using something else).

What I did was create an XSLT which produced a graphviz input file after processing all of the FHIR StructureDefinition inputs.  To create a single XML file, I cheated a bit, and simply ran:

c:\build\publish> for /r %f in (*.profile.xml) type %f >>all.fhir.xml

After that, I edited all.fhir.xml and stripped all the extra XML declarations, and wrapped it in an element named FHIR (in the FHIR namespace).  There are other ways to do that to automate that, but this was simple and easy.  Note: The output will include some things that may have been part of the FHIR Build, but not part of the specification (e.g., Account in STU2).  I dealt with that in a later step.

After that, I used a number of different layouts supported by GraphViz to see which worked.  Just using the basic options produces a drawing about 30" x 150".  That's not really easy to use.  The best layout I could find was sfdp, which produces a clustered layout based on edge weights, using a force dependent spring model.  The layout stilled looked dramatically ugly because the lines overlap the nodes, so I set the edges up to use orthogonal connectors.

That looked close enough to be useful, so the next thing I did was to color code the nodes based on the Resource categorization used on the Resources page.  Clinical resources took on a range of purple colors (by subcategory), identification resources were red, workflow became cyan, infrastructure blue, conformance various shades of gray, and finance was green.  The colors helped me to understand how things were clustering in the diagram, so that I could possibly hand tune it.

I plan on doing hand tuning with a graphics editing tool.  Right now I'm checking out GraphVizio, a Visio plugin that lets me import GraphViz drawings.  Running the compute on the graph through Visio is something that is worthy of a long coffee break (actually, the same is true for the various layout methods).  I'm hoping Visio gets out of my way long enough to make this a worthwhile exercise, otherwise, I may have to revert to some other drawing tools.  I still don't like all the stuff Visio added for connecting stuff.  As soon as I move something a bit, it auto-reroutes stuff I've carefully positioned, screwing things up again.  I haven't played around with it long enough to figure out how to turn that off.

While I'm messing around with the diagram, I thought I'd show my initial progress:

As you can see, there's still a ways to go.  The diagram is still way too big, and you cannot even zoom it large enough to read.  What is interesting is that in fact, the FHIR Resources do tend to cluster, and Patient, Practitioner, and RelatedPerson find themselves at the center of care, just like you might expect.