Convert your FHIR JSON -> XML and back here. The CDA Book is sometimes listed for Kindle here and it is also SHIPPING from Amazon! See here for Errata.

Monday, July 11, 2011

Smells like I dunno...

One of the persistent questions in HL7 Structured Documents on the CDA Consolidation guide is how to say I don't know.  HL7 has flavors of NULL, and in IHE I jokingly discussed "Colors" of None (it became a section on "Distinctions of None" in the PCC TF).  Well, for this, I think we have to work with smells of unknown because the current situation stinks.

The challenge here is the distinction between Boolean logic which you learn in high school, and three-valued logic which geeks like me might have learned in college, or encountered in their first more than simple SQL query.

For medications and problems, IHE solved the challenge of unknown for medications and problems using SNOMED CT.  IHE suggested the use of "Drug Treatment Unknown" from SNOMED CT in the substanceAdministration code element for medications.  For problems it suggested that the observation value element use "Past Medical History Unknown" from SNOMED CT.  But for allergies there is no such code.  The CDA Consolidation project decided that the codes were part of the problem and that this should be manageable using the RIM.

The CDA Consolidation project has now embarked upon looking for a consistent solution using the HL7 RIM.  Ideally such a solution would also be consistent with positive and negative assertions around problems, allergies and medications.

negationInd
All acts in HL7 Version 3 had at one time a "negation indicator" which could negate the act.  So, you could readily say:  I did this or I did not do that.  This has since been subdivided because some acts (the all pervasive Observation) have both an act and a value, and sometimes you want to say that the observation wasn't performed, and other times you want to say that the value wasn't observed.  So now there is an "Action negation indicator" and a value negation indicator.  For CDA, we are still using the original negation indicator until Release 3 when we absorb the new RIM and Data Types.

The Negation Indicator (and its replacements) are indicated to be of the BL type, which supports true, false and NULL.  However, in XML representations where the BL type is used and appears as an attribute, it can ONLY have the values true or false.  So they really aren't of the BL type, rather they are of the BN (Boolean Non-NULL) type in what they can represent.  So even though BL supports three-valued reasoning with unknowns, it doesn't for structural attributes like negationInd.

I'm not sure whether that restriction was intentional (it seems to have been).  It does mean that there are things you can say in the RIM that you cannot say in an XML representation.  In the RIM you can say "I don't know whether this action occurred or did not".  But it cannot be implemented using the XML Implementation Technology specification (ITS) because that specification restricts negationInd to be only true or false and doesn't allow NULL values.  One could argue that the presence of the nullFlavor attribute on the RIM classes in the XML ITS addresses this issue, but it fails to provide a complete representation. In the RIM, you can say, I don't know if the patient received any medication between January 1 and January 12th of 2011, or you can say, I don't know if they received blood thinners between those dates, or at just about any level of detail (just like you can with negation).  I'm not clear on the way nullFlavor works on classes, but it would seem to restrict use of attributes on the class, so you cannot be "broadly uncertain" on the class.

Because the XML ITS doesn't support a nullFlavor on negationInd, CDA doesn't support it either.  So an alternate representation is needed.

uncertaintyCode
There is an alternative supported by all Act classes in the RIM to represent degrees of uncertainty.  Alas that code system only allows for statements of normal, and uncertain statements, and doesn't really get into any real quantification of uncertainty (perfect uncertainty = a true unknown).  But CDA didn't use it (probably because it didn't have much utility as specified), so that isn't even a choice, even if it had a better code system.

extensions
Extensions are right out because the rule about extensions is this:  
These extensions should not change the meaning of any of the standard data items, and receiving applications must be able to safely ignore these elements.
And adding an extension to say that X should be interpreted as being unknown would change the meaning of X, and that it couldn't safely be ignored.

Developing an Alternative
So, lets look at various kinds of I dunno...
  1. It isn't known whether the patient has any diseases.
  2. Patient is known to have a disease, but the identity of the disease is unknown.
  3. It isn't known whether the patient has (or has had) _____. (e.g., Chicken pox).
  4. It's not known whether the patient has any allergies.
  5. Patient is known to have an allergy, but the identity of the allergen is unknown.
  6. It's not known whether the patient is allergic to ____.
  7. It isn't known whether or not the patient is taking any medications.
  8. The patient is known to be on a medication, but that medication is not known.
  9. It isn't known whether a patient has taken medication _____.
There is a pattern here.
  1. I know that a disease/allergy/medication exists, but I don't know what it is.
  2. I don't know whether a specified disease/allergy/medication exists.
  3. I know nothing about diseases/allergies/medications.
Pattern #1
This is relatively easy to represent in CDA using codes.  You need to be able to indicate the type of observation produced an unknown result for problems and allergies.  For meds, that really isn't necessary because the classCode for substanceAdministration tells you that you are dealing with the administration of a substance, and the manufacturedLabledDrug indicates you are talking about a drug.

An unknown Problem
<entry>
  <observation classCode="OBS" moodCode="EVN">
    <code code="64572001" displayName="Disease" 
      codeSystem="2.16.840.1.113883.6.1"/>
    <value xsi:type="CD" nullFlavor="ASKU"/>
  </observation>
</entry>

An unknown Medication
<entry>
  <substanceAdministration moodCode="EVN" classCode="SBADM">
    <consumable>
        <manufacturedProduct>
          <manufacturedLabeledDrug>
            <code nullFlavor="ASKU"/>
          </manufacturedLabeledDrug>
        </manufacturedProduct>
      </consumable>
    </substanceAdministration>
</entry>

An unknown Allergy
<entry>
  <observation classCode="OBS" moodCode="EVN">
    <code code="106190000" displayName="Allergy" 
      codeSystem="2.16.840.1.113883.6.1"/>
    <value xsi:type="CD" nullFlavor="ASKU"/>
    <participant typeCode='CSM'>
      <participantRole classCode='MANU'>
        <playingEntity classCode='MMAT'>
          <code nullFlavor="ASKU"/>
        </playingEntity>
      </participantRole>
    </participant>
  </observation>
</entry>

Pattern #2
This is much more difficult. We want to be able to say that the "status" of the observation is unknown.  This is similar to saying it was negated.  There is a nullFlavor attribute that can be used with the observation.

A Specific Problem is unknown
<entry>
  <observation classCode="OBS" moodCode="EVN" nullFlavor="ASKU">
    <code code="64572001" displayName="Disease" 
      codeSystem="2.16.840.1.113883.6.96"/>
    <value xsi:type="CD" code="38341003" displayName="Hypertensive Disorder" 
codeSystem="2.16.840.1.113883.6.96" codeSystemName="SNOMED CT"/>
</observation>
</entry>

A Specified Medication is Unknown
<entry>
  <substanceAdministration moodCode="EVN" classCode="SBADM" nullFlavor="ASKU">
<consumable>
<manufacturedProduct>
        <manufacturedLabeledDrug>
          <code code="81839001" displayName="anticoagulant drug"
codeSystem="2.16.840.1.113883.6.96" codeSystemName="SNOMED CT"/>
</manufacturedLabeledDrug>
      </manufacturedProduct>
    </consumable>
  </substanceAdministration>
</entry>

A specified Allergy is Unknown
<entry>
  <observation classCode="OBS" moodCode="EVN" nullFlavor="ASKU">
    <code code="106190000" displayName="Allergy" 
       codeSystem="2.16.840.1.113883.6.1"/>
    <value xsi:type="CD" code="300916003" displayName="Latex Allergy"
codeSystem="2.16.840.1.113883.6.96" codeSystemName="SNOMED CT"/>
    <participant typeCode='CSM'>
      <participantRole classCode='MANU'>
        <playingEntity classCode='MMAT'>
          <code code="111088007" displayName="latex"
codeSystem="2.16.840.1.113883.6.96" codeSystemName="SNOMED CT"/>
</playingEntity> </participantRole> </participant> </observation> 
</entry>

Pattern #3
Now that we've solved pattern #2, this one is easy.  We just make the disease, allergen or medication very general to say that we don't know about diseases, medications, or allergies/allergens.

Nothing is known about Problems
<entry>
  <observation classCode="OBS" moodCode="EVN" nullFlavor="ASKU">
    <code code="64572001" displayName="Disease" 
      codeSystem="2.16.840.1.113883.6.96"/>
    <value xsi:type="CD" code='64572001' displayName='Disease'
      codeSystem='2.16.840.1.113883.6.96' codeSystemName='SNOMED CT'/>
</observation>
</entry>

Nothing is known about Medications
<entry>
  <substanceAdministration moodCode="EVN" classCode="SBADM" nullFlavor="ASKU">
<consumable>
       <manufacturedProduct>
         <manufacturedLabeledDrug>
           <code code='410942007' displayName='Drug or Medicament' 
codeSystem='2.16.840.1.113883.6.96' codeSystemName='SNOMED CT'/>
</manufacturedLabeledDrug>
       </manufacturedProduct>
     </consumable>
  </substanceAdministration>
</entry>

Nothing is Known about Allergies
<entry>
  <observation classCode="OBS" moodCode="EVN" nullFlavor="ASKU">
    <code code="106190000" displayName="Allergy" 
      codeSystem="2.16.840.1.113883.6.1"/>
    <value xsi:type="CD" nullFlavor="NA"/>
    <participant typeCode='CSM'>
      <participantRole classCode='MANU'>
        <playingEntity classCode='MMAT'>
          <code code='413477004' displayName='Allergen or Pseudoallergen' 
codeSystem='2.16.840.1.113883.6.96' codeSystemName='SNOMED CT'/>
        </playingEntity>
      </participantRole>
    </participant>
  </observation> 
</entry> 

Now we appear to have solved this problem.  The trick was recognizing that the nullFlavor attribute on the class was essentially where the missing nulls for negationInd disappeared to.  It appears that I managed to sniff out a solution ;-)  ... and it doesn't stink.  In fact, it works pretty consistently across all classes.  I could easily see how to extend it to say that it is unknown whether a patient had a particular procedure or encounter, or even family history of any particular disease.

  -- Keith

P.S.  All the XML Validates against the CDA Schema


This post was updated on July 18th to reflect adjustments made by the HL7 Structured Documents Workgroup based on feedback from Grahame Grieve. The key change was in using a general code rather than unknown for pattern 3.  A similar change was made for How to say No...