Thursday, September 26, 2019

Strange Dreams and Context Controls in HL7 CDA

One of the challenges of a job that requires a lot of thinking is that it's really hard to escape it sometimes.  Last night, just before I head off for a short trip to the cape, I was dreaming about context controls in CDA documents.


Did I just lose you?  Yeah, I was wondering about that myself.

The CDA Document enumerates a number of participations, and for many of these participations, fixes the contextControlCode value to "OP", a code that means Overriding and Propagating, as in the example below from the CDA R-MIM.

What the heck does this mean?

In RIM Speak, context controls describe how the participation applies to not just the act the author participation is attached to (the CDA Document), but also the acts descending downwards (in the direction of the arrows) from the act in which the participation is attached.

So, if you have a CDA Document, it can have sections (a descendant act), which can have entries (a descendant act), and those entries can reference other things (like reference ranges) and so on.  And if, at the top of the document (/ClinicalDocument/author), you say that the author is Alex, then that propagates through the act and all related acts (in the direction of the act relationship arrows) until that same type of participation is again encountered.  At that time, the new participant (Bobbie) overrides the existing one, and propagates downward as the author of all attached and decedent acts.

This behavior is crucial to the way that participations work in CDA, and fortunately, all essential participations work that way.  The way it is crucial is because you can, using XSLT  (yeah, I know, who the hell else do you that dreams in XSLT...) create an XPath expression that identifies the author (or recorder, or performer) of a particular event.

Say you are looking at an allergy in a CCDA Document.  Who's the author of this thing?  Basically, you look at the act (in this case the observation using the allergy template).  If that has an author, you stop there.  Otherwise you look to the act above it to see if it has an author, and so on, all the way to the top of the document (which is /ClinicalDocument), and which, is guaranteed (according to the CDA R-MIM and Schema) to contain at least one author.  Once you find an act that has at least ONE author, you then accumulate all authors as the author of the act.  Assuming your current context is an act that you want to find the author of, here's the XPath expression that identifies all authors of the current act.

ancestor-or-self::cda:*[cda:author][1]/cda:author

What does this say?

ComponentMeaning
ancestor‑or‑self::Starting with the current node and ascending to all of its ancestors in order through the root of the document.
cda:*Find any element ... note, that while this expression will allow traversal through both act and act-relationship links, the next element will only ever be true on acts (because only acts can have author children).
[cda:author]That contains an cda:author element 
[1]Stop after you find the first one
/cda:authorCollect ALL of the authors.

So, this will find the first act that specified an author, and collect all of the authors.  If you are trying to translate from CDA to FHIR, this is an essential tool you can use to find author, informant, subject, or other participant.

You cannot assume that just because Alex authored the document that he / she authored all acts within it.  You have to look.

One important adjustment to this.  The subject of every act is assumed to be the patient, unless subject is otherwise specified, but the patient participation is actually identified through the record target participation in CDA.  This is inference from semantics, rather than true semantics, but that's OK.  The way to adjust for that is to use the following to get to the "subject" of the act:

ancestor-or-self::cda:*[cda:subject|cda:recordTarget][1]/(cda:subject|cda:recordTarget)

You may have to fiddle a bit around the use of parentheses depending on whether you are working in XSLT 1.0 or 2.0 (or even 3.0), but you should be able to make it work.

     Keith

0 comments:

Post a Comment