Showing posts with label C32. Show all posts
Showing posts with label C32. Show all posts

Monday, October 9, 2017

Where do I find the Medication Generic Name in a CCD Document

The answer is, it depends on your CCD version:

CCDA 2.1 has this to say:
 4. SHALL contain exactly one [1..1] manufacturedMaterial (CONF:1098-7411).
     Note: A medication should be recorded as a pre-coordinated ingredient + strength + dose form (e.g., “metoprolol 25mg tablet”, “amoxicillin 400mg/5mL suspension”) where possible. This includes RxNorm codes whose Term Type is SCD (semantic clinical drug), SBD (semantic brand drug), GPCK (generic pack), BPCK (brand pack).
     1. This manufacturedMaterial SHALL contain exactly one [1..1] code, which SHALL be selected from ValueSet Medication Clinical Drug urn:oid:2.16.840.1.113762.1.4.1010.4 DYNAMIC (CONF:1098-7412).
         1. This code MAY contain zero or more [0..*] translation, which MAY be selected from ValueSet Clinical Substance urn:oid:2.16.840.1.113762.1.4.1010.2 DYNAMIC (CONF:1098-31884).

CCDA 1.1 has this to say:
 4. SHALL contain exactly one [1..1] manufacturedMaterial (CONF:81-7411).
     Note: A medication should be recorded as a pre-coordinated ingredient + strength + dose form (e.g., “metoprolol 25mg tablet”, “amoxicillin 400mg/5mL suspension”) where possible. This includes RxNorm codes whose Term Type is SCD (semantic clinical drug), SBD (semantic brand drug), GPCK (generic pack), BPCK (brand pack).
     1. This manufacturedMaterial SHALL contain exactly one [1..1] code, which SHALL be selected from ValueSet Medication Clinical Drug urn:oid:2.16.840.1.113762.1.4.1010.4 DYNAMIC (CONF:81-7412).
         1. This code SHOULD contain zero or one [0..1] originalText (CONF:81-7413).
             1. The originalText, if present, SHOULD contain zero or one [0..1] reference (CONF:81-15986).
                 1. The reference, if present, SHOULD contain zero or one [0..1] @value (CONF:81-15987).
                     1. This reference/@value SHALL begin with a '#' and SHALL point to its corresponding narrative (using the approach defined in CDA Release 2, section 4.3.5.1) (CONF:81-15988).
         2. This code MAY contain zero or more [0..*] translation (CONF:81-7414).
             1. Translations can be used to represent generic product name, packaged product code, etc (CONF:81-16875).

HITSP C32 has this to say (you can actually find this in the HITSP C83 specification):
2.2.2.8.13 Free Text Product Name Constraints
C83-[DE-8.15-CDA-1] The product (generic) name SHALL appear in the <originalText> element beneath the <code>

It's pretty clear that the preferred way to handle this changed in between CCD 1.0 (HITSP C32) and CCDA 1.1, and also that some critical information loss occurred with regard to how to record generic name between CCDA 1.1 and 2.1.  I think as industry understanding of CDA expanded, the need to express the detail about generic name probably changed, but not necessarily for the better.

If you want to include generic name, you would do it in a translation -- when you don't already list the drug using an RxNORM code from the Semantic Clinical Drug value set (generic codes) (e.g., you use a Semantic Branded Drug code).

I have two statements to make about this:

  1. Not all implementers are informaticists or would understand the distinction between types of RxNorm codes.  We (HL7) need to remember to speak to who is doing the work, not to ourselves.
  2. Brand and Generic information is already represented as relationships embedded in the RxNorm terminology itself.  The simultaneous transmission of a brand code and a generic code for that same drug simply repeats what is already present in RxNorm.  The advice I give these days would be to trust RxNorm before you trust your trading partner, and if what your trading partner tells you CONFLICTS, someone needs to go raise a red flag about inconsistent data.

   Keith



Monday, August 13, 2012

Moving on from C32: Lab Results

The Lab Results section is required to demonstrate compliance with Meaningful Use requirements for both Ambulatory and Inpatient settings.  However, there’s always been some question what to do when no Labs were performed during a visit. In CCD 1.1, the Results section is required, so that question has been answered.  It’s not the answer that I would have given, but there you have it.  Include a results section, whether you have any or not.  I’ll address what an Empty results section should look like below.

<section>
  <templateId root="2.16.840.1.113883.3.88.11.83.122"/>
<templateId root="1.3.6.1.4.1.19376.1.5.3.1.3.28"/>
<templateId root="2.16.840.1.113883.10.20.22.2.3"/>
  <templateId root="2.16.840.1.113883.10.20.22.2.3.1"/>
  <code code="30954-2" codeSystem="2.16.840.1.113883.6.1"
        codeSystemName="LOINC" displayName="Results"/>
  <title>Diagnostic Results</title>
  <text>…</text>
    …
  <entry> … See Results Organizer Below … </entry>
</section>


Results Organizer

The major change in this section is that we dropped the requirement for the <procedure> in the organizer. This was always confusing and appeared in IHE and HITSP part as a result of my inaccurate understanding of HL7 classes back in 2005.  I could never get the intent corrected, as much as I tried, until now.  In the RIM, procedure brings about a change in the patient, an observation doesn’t.  In medical documents, a procedure (note) documents an observation (class), and an operative (note) documents a procedure (class).  Confused?  I was.

Again, for this, the big change is the template Identifier.  The vocabulary that CCD 1.1 allows for on <code> is to identify the type of panel or test ordered, and could be the code for the panel, a category of tests, or a specific result.  I would recommend the LOINC code for the test being ordered.  Meaningful test methods will make it clear what is required here.  Stage 2 requires LOINC to identify lab results, but the <code> on organizer classifies the results beneath it.  So it isn’t totally clear this must be LOINC for Meaningful Use Stage 2, but using LOINC is probably the safest bet here.

<entry>
       <organizer classCode="BATTERY" moodCode="EVN">
              <templateId root="2.16.840.1.113883.10.20.22.4.1"/>
              <templateId root="2.16.840.1.113883.10.20.1.32"/>
              <id root="7d5a02b0-67a4-11db-bd13-0800200c9a66"/>
              <code code="58410-2" codeSystem="2.16.840.1.113883.6.1"
                     displayName="CBC" codeSystemName="LOINC"/>
              <statusCode code="completed"/>
              <effectiveTime value="200003231430"/>
              <!-- This can be removed -->
              <component>
                     <procedure classCode="PROC" moodCode="EVN">
                            <templateId root="2.16.840.1.113883.3.88.11.83.17"/>
                            <templateId root="2.16.840.1.113883.10.20.1.29"/>
                            <templateId root="1.3.6.1.4.1.19376.1.5.3.1.4.19"/>
                                  …
                     </procedure>
              </component>
              <component> … See Results Observation Below … </component>
       </organizer>
</entry>


Results Observation

For the results observation, mostly you just need to swap out templateId values.  Note that if you have local codes, they go into the <translation> now.  While CCD 1.1 allows for other vocabulary in the <code> element, you’ll need to use LOINC for the actual <code>, at least according to the proposed Meaningful Use rules.  NOTE:  If you include <referenceRange> and had a <code> element in it, it must be removed according to CCDA.

<component>
       <observation classCode="OBS" moodCode="EVN">
              <templateId root="2.16.840.1.113883.10.20.22.4.2"/>
              <templateId root="2.16.840.1.113883.3.88.11.83.15.1"/>
              <templateId root="2.16.840.1.113883.10.20.1.31"/>
              <templateId root="1.3.6.1.4.1.19376.1.5.3.1.4.13"/>
              <id root="107c2dc0-67a5-11db-bd13-0800200c9a66"/>
              <code code="30313-1" codeSystem="2.16.840.1.113883.6.1" 
                   displayName="HGB">
                <translation code="…" codeSystem="…" codeSystemName="LOCAL"/>
              </code>
              <text><reference value="#TESTSUMMARY_1"/></text>
              <statusCode code="completed"/>
              <effectiveTime value="200003231430"/>
              <value xsi:type="PQ" value="13.2" unit="g/dl"/>
              <interpretationCode code="N" codeSystem="2.16.840.1.113883.5.83"/>
              <referenceRange>
                  <code ... />
                  <observationRange>
                     <text>M 13-18 g/dl; F 12-16 g/dl</text>
                  </observationRange>
              </referenceRange>
       </observation>
</component>


No Results to Report

OK.  This isn’t pretty.  I’m sorry.  All I can say is that it isn’t my fault. 

The CCD 1.1 requires a Lab Results section.  The organizer needs to be present in the section according to the Result Section rules.

But: We don’t give it a code because we don’t have to, nor does it have an identifier.  The organizer represents an event that occurred (you cannot negate the act of organizing), so you can say when you created the organizer (e.g., the date of the encounter you are building the CCD for).

Inside the organizer is an observation that negates the code for Laboratory Studies.  That basically says “I did no laboratory studies”.  Adding effectiveTime limits the negation to the specified date. 


<section>
<templateId root="2.16.840.1.113883.10.20.22.2.3"/>
   <templateId root="2.16.840.1.113883.10.20.22.2.3.1"/>
   <code code="30954-2" codeSystem="2.16.840.1.113883.6.1"
         codeSystemName="LOINC" displayName="Results"/>
   <title>Diagnostic Results</title>
   <text>No Laboratory Tests Performed</text>
   <entry>
      <organizer classCode="CLUSTER" moodCode="EVN">
         <templateId root="2.16.840.1.113883.10.20.22.4.1"/>
         <id nullFlavor="NA"/>
         <code nullFlavor="NA"/>
         <statusCode code="completed"/>
         <effectiveTime value="200003231430"/>
         <component>
            <observation classCode="OBS" moodCode="EVN" negationInd="true">
                <templateId root="2.16.840.1.113883.10.20.22.4.2"/>
                <id nullFlavor="NA"/>
                <code code="26436-6" codeSystem="2.16.840.1.113883.6.1"
                      displayName="Laboratory Studies" codeSystemName="LOINC"/>
                <statusCode code="completed"/>
                <effectiveTime value="200003231430"/>
            </observation>
          </component>
      </organizer>
   </entry>
</section>

I don’t like this. It would have been vastly simpler to allow the section to be omitted in its entirety, or to specify a much simpler observation that indicated that no lab results were performed, but at least this should work.

Wednesday, August 1, 2012

Moving on from HITSP C32: The CCDA Problems and Allergies Section

Continuing from yesterday’s post, I’ll look at what you need to do with the problems section.  And because Allergies are a specialization of problems, and the changes are related, I’ll do that section as well.
This one is the most challenging, because the new problem concern isn’t backwards compatible with the HITSP C32 version.  It means that you cannot create something that is both a CCD 1.0 and a CCD 1.1 at the same time.

The Problem Section

Adjusting the section is just a matter of swapping out template identifiers.  It is actually the entries within the section that need further alteration.
In the problem section, remove the templateId elements that have been struck out, and add the ones in bold and underline.
<component>
   <section>
      <templateId root="2.16.840.1.113883.10.20.1.11"/>
      <templateId root="1.3.6.1.4.1.19376.1.5.3.1.3.6"/>
      <templateId root="2.16.840.1.113883.3.88.11.83.103"/>
      <templateId root="2.16.840.1.113883.10.20.22.2.5"/>
      <templateId root="2.16.840.1.113883.10.20.22.2.5.1"/>
      <code code="11450-4" codeSystem="2.16.840.1.113883.6.1"
         codeSystemName="LOINC" displayName="PROBLEM LIST"/>
      <title>PROBLEMS</title>
      <text> … </text>
      <entry> … </entry>
   </section>
</component>

The Allergy Section

Just as in the problems section, the allergies section will also require swapping out identifiers, and the real focus is on the entries.
<component>
   <section>
      <templateId root="2.16.840.1.113883.10.20.1.2"/>
      <templateId root="1.3.6.1.4.1.19376.1.5.3.1.3.13"/>
      <templateId root="2.16.840.1.113883.3.88.11.83.102"/>
      <templateId root="2.16.840.1.113883.10.20.22.2.6"/>
      <templateId root="2.16.840.1.113883.10.20.22.2.6.1"/>
      <code code="48765-2" codeSystem="2.16.840.1.113883.6.1" codeSystemName="LOINC"
         displayName="Allergies, adverse reactions, alerts"/>
      <title>PROBLEMS</title>
      <text> … </text>
      <entry> … </entry>
   </section>
</component>


The Problem Concern

In the CCD 1.0 and HITSP C32 (and the IHE templates in between), the “Problem Concern” did double duty, representing the “Concern” act for both problems and allergies.  In the CDA Consolidation Guide, this act was split into two different templates, one to address problems, and the other to address allergies.  Structurally, they are very similar.  We’ll take on the changes for problem first:
<act classCode="ACT" moodCode="EVN">
   <templateId root="2.16.840.1.113883.3.88.11.83.7"/>
   <templateId root="2.16.840.1.113883.10.20.1.27"/>
   <templateId root="1.3.6.1.4.1.19376.1.5.3.1.4.5.1"/>
   <templateId root="1.3.6.1.4.1.19376.1.5.3.1.4.5.2"/>
   <templateId root="2.16.840.1.113883.10.20.22.2.5"/>
   <id root="6a2fa88d-4174-4909-aece-db44b60a3abb"/>
   <code nullFlavor="NA"/>
   <code code="CONC" codeSystem="2.16.840.1.113883.5.6"/>
   <statusCode code="completed"/>
   <effectiveTime>
      <low value="1950"/>
      <high nullFlavor="UNK"/>
   </effectiveTime>
   <entryRelationship
      typeCode="SUBJ" inversionInd="false">
   <observation classCode="OBS" moodCode="EVN">
      <templateId root="2.16.840.1.113883.10.20.1.28"/>
      <templateId root="1.3.6.1.4.1.19376.1.5.3.1.4.5">
      <templateId root="2.16.840.1.113883.10.20.22.4.4"/>
         …
   </observation>
</act>

As you can see, the “breaking change” was for the <code> element, and a different template for the problem observation. 

The Allergy Concern

Moving on now to allergies, again, what changed was <code> and the use of a different template for the allergy observation. 
<act classCode="ACT" moodCode="EVN">
   <templateId root="2.16.840.1.113883.3.88.11.83.6"/>
   <templateId root="2.16.840.1.113883.10.20.1.27"/>
   <templateId root="1.3.6.1.4.1.19376.1.5.3.1.4.5.1"/>
   <templateId root="1.3.6.1.4.1.19376.1.5.3.1.4.5.3"/>
   <templateId root="2.16.840.1.113883.10.20.22.4.30"/>
   <id root="36e3e930-7b14-11db-9fe1-0800200c9a66"/>
   <code nullFlavor="NA"/>
   <code code="48765-2"
      codeSystem="2.16.840.1.113883.6.1"
      codeSystemName="LOINC"
      displayName="Allergies, adverse reactions, alerts"/>
   <statusCode code="completed"/>
   <effectiveTime>
     <low nullFlavor="UNK"/>
     <high nullFlavor="UNK"/>
   </effectiveTime>
   <entryRelationship typeCode="SUBJ" inversionInd="false">
     <observation classCode="OBS" moodCode="EVN">
         <templateId root="2.16.840.1.113883.10.20.1.18"/>
         <templateId root="2.16.840.1.113883.10.20.1.28"/>
         <templateId root="1.3.6.1.4.1.19376.1.5.3.1.4.5"/>
         <templateId root="1.3.6.1.4.1.19376.1.5.3.1.4.6"/>
         <templateId root="2.16.840.1.113883.10.20.1.18"/>
         <templateId root="2.16.840.1.113883.10.20.22.4.7"/>
        …
     </observation>
   </entryRelationship>
</act>


Problem Observations

Now we move into the problem and allergy observation templates.  Again, I’ll start with the problem observation.  Note that here you need only add the CCD 1.1 template identifier, and don’t have to remove the prior template identifiers because the two templates are compatible (but see my notes below on backwards compatibility).
The same is true for the problem status observation contained inside the problem observation.  Note that HITSP C32 suggested pointing to the problem text in the value element, while CCD 1.1 does not.  It’s still allowed, and gives you a way to textually describe problems which are not coded.
<observation classCode="OBS" moodCode="EVN">
   <templateId root="2.16.840.1.113883.10.20.1.28"/>
   <templateId root="1.3.6.1.4.1.19376.1.5.3.1.4.5"/>
   <templateId root="2.16.840.1.113883.10.20.22.4.4"/>
   <id root="d11275e7-67ae-11db-bd13-0800200c9a66"/>
   <code code="64572001" displayName="Condition"
     codeSystem="2.16.840.1.113883.6.96" codeSystemName="SNOMED-CT"/>
   <text>
     <reference value="#PROBSUMMARY_1"/>
   </text>
   <statusCode code="completed"/>
   <effectiveTime>
     <low value="1950"/>
   </effectiveTime>
   <value xsi:type="CD" displayName="Asthma" code="195967001"
     codeSystemName="SNOMED" codeSystem="2.16.840.1.113883.6.96">
     <originalText>
      <reference value="#PROBSTATUS_1"/>
     </originalText>
   </value>
   <!-- Problem Status Template -->
   <entryRelationship typeCode="REFR">
     <observation classCode="OBS" moodCode="EVN">
      <templateId root="2.16.840.1.113883.10.20.1.50"/>
      <templateId root="2.16.840.1.113883.10.20.22.4.6"/>
      <code code="33999-4" codeSystem="2.16.840.1.113883.6.1"
         displayName="Status"/>
      <statusCode code="completed"/>
      <value xsi:type="CE" code="55561003"
        codeSystem="2.16.840.1.113883.6.96" displayName="Active">
      </value>
     </observation>
   </entryRelationship>
</observation>



Allergy Observation

The allergy observation and its subordinate observations are going to require a few more adjustments because of the contained <participant> describing the allergen, and the shifting of the type of allergy from <code> to <value>, among other things.
<observation classCode="OBS" moodCode="EVN">
   <templateId root="2.16.840.1.113883.10.20.1.18"/>
   <templateId root="2.16.840.1.113883.10.20.1.28"/>
   <templateId root="1.3.6.1.4.1.19376.1.5.3.1.4.5"/>
   <templateId root="1.3.6.1.4.1.19376.1.5.3.1.4.6"/>
   <templateId root="2.16.840.1.113883.10.20.1.18"/>
   <templateId root="2.16.840.1.113883.10.20.22.4.7"/>
   <id root="4adc1020-7b14-11db-9fe1-0800200c9a66"/>
   <code code="416098002" codeSystem="2.16.840.1.113883.6.96"
      displayName="drug allergy" codeSystemName="SNOMED CT"/>
   <code code="ASSERTION" codeSystem="2.16.840.1.113883.5.4"/>
   <!-- No longer required or recommended in CCDA, but do it anyway -->
   <text>
     <reference value="#ALGSUMMARY_1"/>
   </text>
   <statusCode code="completed"/>
   <effectiveTime>
     <low nullFlavor="UNK"/>
   </effectiveTime>
   <value xsi:type="CD" code="70618" codeSystem="2.16.840.1.113883.6.88"
      displayName="Penicillin" codeSystemName="RxNorm">
      <originalText>
         <reference value="#ALGSUB_1"/>
      </originalText>
   </value>
   <!-- Put what used to go into <code> here -->
   <value xsi:type="CD" code="282100009" 
      displayName="Adverse reaction to substance"
      codeSystem="2.16.840.1.113883.6.96" codeSystemName="SNOMED CT">
   </value>
   <!-- This is pretty much unchanged (and ought to be a template) -->
   <participant typeCode="CSM">
     <participantRole classCode="MANU">
      <playingEntity classCode="MMAT">
        <code code="70618" codeSystem="2.16.840.1.113883.6.88"
          displayName="Penicillin" codeSystemName="RxNorm">
          <originalText>
           <reference value="#ALGSUB_1"/>
          </originalText>
        </code>
        <name>Penicillin</name>
      </playingEntity>
     </participantRole>
   </participant>
   <entryRelationship typeCode="MFST" inversionInd="true">
     <observation classCode="OBS" moodCode="EVN">
      <templateId root="2.16.840.1.113883.10.20.1.54"/>
      <templateId root="2.16.840.1.113883.10.20.22.4.9"/>
      <!-- Reaction observation template -->
      <code code="ASSERTION" codeSystem="2.16.840.1.113883.5.4"/>
      <text><reference value="#REACTION-1"/></text>
      <statusCode code="completed"/>
      <value xsi:type="CD" code="247472004"
        codeSystem="2.16.840.1.113883.6.96" displayName="Hives">
        <originalText>
          <reference value="#ALGREACT_1"/>
        </originalText>
      </value>
      <entryRelationship typeCode="SUBJ">
         <observation classCode="OBS" moodCode="EVN">
           <templateId root="2.16.840.1.113883.10.20.1.55"/>
           <templateId root=" 2.16.840.1.113883.10.20.22.4.8"/>
           <!-- Severity observation template -->
           <code code="SEV" displayName="Severity"
           codeSystemName="HL7 ActCode" codeSystem="2.16.840.1.113883.5.4"/>
           <text><reference value="#SEVERITY-1"/></text>
           <statusCode code="completed"/>
           <value xsi:type="CE" displayName="moderate" code="6736007"
           codeSystemName="SNOMED" codeSystem="2.16.840.1.113883.6.96"/>
         </observation>
        </entryRelationship>
     </observation>
   </entryRelationship>
   <entryRelationship typeCode="REFR">
     <observation classCode="OBS" moodCode="EVN">
      <templateId root="2.16.840.1.113883.10.20.1.39"/>
      <templateId root="2.16.840.1.113883.10.20.22.4.28"/>
      <!-- Alert status observation template -->
      <code code="33999-4" codeSystem="2.16.840.1.113883.6.1"
        displayName="Status"/>
      <statusCode code="completed"/>
      <value xsi:type="CE" code="55561003" codeSystem="2.16.840.1.113883.6.96"
        displayName="Active">
        <originalText>
          <reference value="#ALGSTATUS_1"/>
        </originalText>
      </value>
     </observation>
   </entryRelationship>
</observation>


On Severity

While I showed the severity template above  in the context of a reaction, the CCDA allows that it can also be used for allergies themselves.  And I note that it doesn’t forbid it from being used in problems, it just didn’t suggest it.  I’m suggesting it.  Severity is simply a special kind of annotation on an problem, allergy, or reaction.  Don’t expect it to be present, or supported by all systems, but if you have it, be kind and share it with others.

On Backwards Compatibility

The new templates for problems and allergies are functionally compatible with the HITSP C32 specifications.  In other words, you can say the same things.  In a few cases, they are even wire compatible.  That is to say that you can create XML that would be valid in both the HITSP C32, and the CCD 1.1.  The question to ask yourself though, is whether you want to take that on.  My advice would be to NOT try to retain compatibility in the same package even if it is technically feasible. 

CCDA takes a different enough approach that you’ll run into challenges.  While this series focuses on production, consumption is a completely different story.  You aren’t in control of what you are going to receive, so you have to be able to accept anything that’s valid. 

That means you cannot take a path of least change to adapt your consumer the way that you can for your producer.  So, create a new package for your CCDA Consumer.  You can start with the same code base you used for the HITSP C32, but you’ll be making enough changes that the end result will be quite a bit different. 

And remember, there will be some time when you still have to deal with both, or at least your customers will.  Not everyone will be able to transition on the same day.  You need to allow for asynchronous bilateral cutover.  It is after all, one of the new ABC’s of interoperability.

Caveats

If it says SHOULD, DO IT.  You will thank me later, or at least, your customer or downstream trading partner will.  SHOULD doesn’t mean “avoid this if you can”, it means that this practice is recommended for maximum interoperability.

If you used additional HITSP C32 templates in these observations, LOOK at them!  I cannot cover everything here, and this post is already TL;DR length.  Furthermore, I offer this information for your education.  Please take responsibility for ensuring the accuracy for your own implementations.

Monday, July 30, 2012

Moving from HITSP C32 to CCD 1.1

This is the first of a series of posts describing how to move from the HITSP C32 required under Meaningful Use to the CCDA specifications.  Since HITSP C32 was a CCD, the plan is to cover how to deal with changes between the HITSP C32 restrictions on CCD, and the HL7 CCDA version of CCD (CCD 1.1).

I'm assuming that you are going to be starting from your existing HITSP C32 implementations to support the new format.  I'm doing this by manually editing the Robust HITSP C32 example provided by NIST, and manually inspecting my changes against the CCD 1.1 specification in the HL7 CDA Consolidation Guide (when there is other testing available, I'll take advantage of that as well).

I’m first going to address the header constraints.  Later posts will address problems, allergies, medications, lab results and procedures sections, and if there is enough demand, I'll get to other sections as well.  You'll be able to find all of these posts under the 2S2 category.

The CCD 1.1 Header

You’ll need to add two <templateId> elements to the existing set under <ClinicalDocument> to conform to the CCD 1.1 Header constraints. 

  <!-- Added for CCDH: CONF:9441 -->
  <templateId root="2.16.840.1.113883.10.20.22.1.1"
       assigningAuthorityName="HL7/CCDA General Header"/>
  <!-- Added for CCDH: CONF:8450 -->
  <templateId root="2.16.840.1.113883.10.20.22.1.2"
       assigningAuthorityName="HL7/CCD 1.1"/>

The “Robust CCD” example from NIST needs no further alterations to be valid for the “CCD Header Constraints”, but we still have yet to deal with the General Header Constraints.  We’ll hit those next.

General Header Constraints

The H&P General Header Constraints were largely adopted in CCDA, but there are a few additional things that you need to worry about:
templateId elements have obviously changed.
The requirements for id, code, and title in the ClinicalDocument have not.
languageCode changes slightly in that the original General Header Constraints specified the nn or nn-CC form, which is still acceptable, but the CCDA allows anything from the valueSet 2.16.840.1.113883.1.11.11526, which is defined by RFC-4646.  That RFC is a bit more forgiving, but most users of it will follow the general nn or nn-CC pattern.
Most of the changes are minor and affect what you can expect in participants in the header:

On addr and telecom

As before, many participants must have an addr and telecom element.  However, the new CCDA header has tighter constraints on what can be present in addr, and looser constraints on telecom.
The tighter constraints on addr ensured that addresses could be stored in information systems without having to parse them:
The address is fielded into streetAddressLine, city, state, postalCode and country elements, where the first two are required, remaining three are recommended.  Non-whitespace text outside of elements inside the <addr> is not permitted. 
For telephone numbers, we had stricter requirements In the original General Header.  We had specified that phone numbers appeared in a constrained form of the tel: URL format.  The older constrained form is described below:

telephone-url = telephone-scheme ':' telephone-subscriber
telephone-scheme = 'tel'
telephone-subscriber = global-phone-number [ extension ]
global-phone-number = '+' phone-number
phone-number = digits
digits = phonedigit | digits phonedigit
phonedigit = DIGIT | visual-separator
extension = ';ext=' digits
visual-separator = '-' | '.' | '(' | ')'
                 
CONF-HP-12: Telephone numbers SHALL match the regular expression pattern tel:\+?[-0-9().]+
CONF-HP-13: At least one dialing digit SHALL be present in the phone number after visual separators are removed.

These constraints are no longer present in the CCDA General header, but are still considered to be best practice in sending phone numbers.  NOTE: If you apply the constraints of the tel: URL from RFC-3966 (or its predecessor RFC-2806) , the lack of a global phone number (a number beginning with a +) requires use of the phone-context= attribute somewhere in the URL, and if you don’t have that, the URL is not correct.  So, the + form is still preferable.

Patients

The administrativeGenderCode and birthTime elements are still required (and administrativeGenderCode still uses the HL7 vocabulary).  The maritalStatusCode, religiousAffiliationCode, raceCode, and ethnicGroupCode elements are still optional (although maritalStatusCode is now recommended.  These use the same vocabularies as was required in the HITSP C32.
Only one <name> element is permitted in the <patient> element.  HITSP C32 allowed multiple names to be present. 
The <name> element in the new general header is now constrained to require being fielded into components for patients, just as was done in the HITSP C32.

Authors

Authors must contain an <id> element that contains their NPI.  This is a new requirement in the CCDA general header, and you will find it in a number of places, starting with the <author> element.  It isn’t clear how you indicate that the author either doesn’t have an NPI (possible) or what to do when the NPI is unknown. 

If you do not have the author’s NPI, I would recommend this form:
<id root='2.16.840.1.113883.4.6' nullFlavor='UNK'/>

And if they do not have one, this form:
<id root='2.16.840.1.113883.4.6' nullFlavor='NA'/>

The first one indicates that you either don’t know the NPI, or it isn’t applicable (in the second one).  HL7 modeling experts will probably hate these choices, but what else should we do?  This is similar to the old how do I say the patient’s phone number is unknown problem that was solved in a similar fashion years ago.

The <name> element can be fielded, like the patient’s name, or it can just be a string containing the full name of the author, but you cannot mix the two as you could have under the HITSP C32 (not that anybody really tried to do that).

If the author is a medical device, you must include both <manufacturerModelName> and <softwareName>.
 

Data Enterer

Data enterers now require an id, address and telephone number (addr and telecom elements), unlike what was required for HITSP C32.  And if you have an NPI for the data enterer, you should include it.  I’m not sure this isn’t a copy and paste error.

Informant

In the HITSP C32, when the informant was an assignedEntity (a healthcare provider), they must have an address (and it is optional for others).  In CCDA, all informants SHOULD have an address, regardless of who they are.  Again, the name must either be fielded, like the patient name, or just a string.

In HITSP C32, an informant that was not a healthcare provider, was restricted to in the kinds of relationships they could have with the patient.  All of those relationships are still permissible, but other types of relationships can also be used.

Information Recipient

In the old general header, if you had an <intendedRecipient> element, you also had to have either an <informationRecipient> or <recievedOrganization>.  In CCDA, neither are required, but if you do that, basically, you might as well have omitted the element.

Legal Authenticator and Authenticator

Ensure that you include <time value='yyyymmdd'/> and <signatureCode code='S'/> in these elements.  A CCDA should have a Legal Authenticator, and may have other authenticators.  The old general header made no recommendations on the presence of the legal authenticator.

That about covers it for this first installment.  Look for future installments over the next few weeks.

Wednesday, December 14, 2011

Integrating Schematron Rules and Clinical Terminology Services

On one of the discussions on the Structured Document Work's CCD mailing list, a member notes that Schematron validation such as that found in the NIST Validator doesn't support validation of content using restricted value sets well.  He's right in that Schematron doesn't include an explicit mechanism designed to perform validation against value sets.  But there is a way to integrate a clinical terminology service into a Schematron rule set using the XSLT document() function and Schematron <let> statement along with appropriately structured rules.  The IHE SVS profile was designed to support this sort of validation, as I mention in a previous post.

For validation, their are two practical classifications of value sets: Those that can be enumerated fully in single XML document, and those which cannot practically be enumerated.  The dividing line is based on the available system memory for the Validator.  I would expect that value sets containing hundreds of elements could practically be enumerated in full, but those containing thousands or more terms would not be practically enumerable.  Note that I do not address issues of "static" vs. "dynamic" value sets here, because the value sets can be enumerated dynamically through a web service call.

The mechanism for validating the smaller value sets in Schematron is to create a variable that contains the content of an XML document.  This is done at the top of the Schematron using the <let> statement:

<sch:let name='ValueSet' value='document("https://example.com/RetrieveValueSet?id=1.2.840.10008.6.1.308")'/>

Later in the Schematron rule set, you'd have a rule context where you would use that variable as follows:

<sch:rule context='cda:manufacturedMaterial/cda:code'>
  <sch:assert test='$ValueSet//svs:Concept[@code = current()/@code'>
   ... report error if concept is not found ...
  </sch:assert>
</sch:rule>

This idea was used in CDA Implementation guide Schematrons as far back as 2005, in the Schematron use for the Care Record Summary release 1.0.  In that Schematron, an external file was used (so the URL would have been file:voc.xml), rather than an HTTP URL.

Now, when the value set is large (such as a list of LOINC Lab Results, SNOMED CT problems, or RxNORM Drugs), it's not practical to enumerate every term because the resulting document would be very large.  In these cases, you could enhance the SVS defined Web Service to support a code parameter.  When this parameter was present, the service would return the entry for the single code in that value set when present, or an empty ConceptList if it didn't exist.  The rule context remains the same in this case, but the assertion changes:


  <sch:assert test='document(concat("https://example.com/RetrieveValueSet?id=1.2.840.10008.6.1.308&code=",@code)//svs:Concept'>
   ... report error if concept is not found ...
  </sch:assert>

In this example, the HTTP Web Service request is dynamically created.  If it returns an empty code list, the rule fails, but if it finds the code, the rule succeeds.

So, while Schematron itself does not support "validation against value sets", appropriate integration with a Clinical Terminology Service and a very simple RESTful API does enable it.  I hope that the NIST Validator takes advantage of this approach in the future.

Thursday, August 4, 2011

C32 questions now being routed through Australia

Grahame Grieve has an "Ask me a question button" on his blog. He routed this one my way:
1.What is difference between various documents published by IHE and
HITSP. they looks similar
For example HITSP C28 vs IHE(Emergency Department Encounter Summary)
2. IHE profiles provide the sections of a clinical documents, but how
do i know what are the data elements a section may have and the XML
representation of the data elements.
EG.for Review of Systems what are the data elements we may have inside
the ENTRY tag.
3. if i create a database using all data elements from HITSP C-83,
would that be good enough to store all data elements i may receive in
all kind of CDA(C28,C48, XDS-MS, healtstory etc) documents.
The HITSP specifications are based up, and refer to the content of the IHE specifications.  For example, HITSP C28 makes use of the IHE EDES profile and requires a conforming instance to also comply with the IHE requirements.

With regard to the data elements that a section may have, HITSP and IHE both have required entries which are described within their respective sections.  Any entry required by IHE is also required by HITSP, and HITSP has additional vocabulary requirements, so you can locate the necessary entries within the HITSP C83 document.  Other entries are permitted by both IHE and HITSP.  They simply aren't specified.  This stems from the idea that these are open templates that others could further constrain by adding new requirements for a more specific use case.

With regard to using the data elements from the HITSP C83, that would be good enough to understand all HITSP specified data elements that you might receive, but it is NOT an exhaustive list due to the openness described above.  That being said, if it can be done using a HITSP template, C83 does say you have to use the HITSP specification for it.

Now, to add that "Ask me a question button" to this blog.

Wednesday, March 16, 2011

On the New Format for HL7 CCD Training, and some stats on The CDA Book

I'm teaching CDA and CCD this week at the HL7 Education Summit.  We're delivering the training in a new format developed by Diego Kaminker, Co-chair of the HL7 Education Workgroup and HL7 Argentina Chair.  Diego did a great job restructuring the training, and I envy the students that got it.  What's different?  Well, I usually spend a half-day on CCD, but today we spent a full day.  The additional time was used for exercises creating a HITSP C32 compliant CCD document.

Also, all the students in today's CCD-focused session spent the day before with Diego and Calvin Beebe (HL7 Structured Documents co-chair) on CDA basics, so I knew what the students already knew about CDA going into the class.  That changes things dramatically in how I teach.  I don't need to spend time for any remedial work in the class for those students who don't have the prerequisite skills or training.  It means that I can draw on and help to reinforce the students existing knowledge.  

Because the class was focused on Meaningful Use implementation, most of the students had already been, or were immediately going to be applying their skills.  Having motivated students makes for a much more interesting classroom environment.  I think I enjoyed this class just as much as the students did.
Even though the class was focused on Meaningful Use, we had two students from Canada who were interested to see what we were doing in the US.  One of them commented about how much Meaningful Use in the US was affecting the International EHR market.  It was a rather astute observation.

After the class, Calvin, Diego and I had dinner and talked about further improvements we want to make based on the students feedback. And they gave great feedback on what we had done, which will further improve this training for others.  While the next Ed Summit reverts to the original format, the November Ed summit will probably reuse the new format.  That will give us enough time to make some of the improvements we discussed.  I also will be teaching the CCD class a little bit differently going forward, based on some of the outcomes of this class.

After dinner, Calvin asked me how much time I spent writing The CDA Book.  He estimated about 1000 hours.  I guessed about 500.  After I got back to my room, I tallied up the stats Microsoft Word keeps on editing time.  I have two documents which were corrupted by Word, and 21 uncorrupted saved copies of the work in progress.  Counting up the editing time I spent, and filling in for the corrupted gaps I'm looking at about 850 hours for the book, outline and proposal.  Adding in time I spent pitching the book to three editors, acquiring equipment and software, and preparing graphics, I figured it was still under 1000 hours.  But, I get page layouts this week to proof, so figure another chunk of time there, and time to promote it and some other stuff, and Calvin probably nailed it on the head.

I started the project in Mid-November of 2009, and delivered it to the publisher in Early November of 2010, so figure a year of elapsed time.  1000 hours is half a working year for most people (50 weeks X 40 hours = 2000 hours).  I know I already spend too much time doing what I do for the day job, and this was after hours, so I figure that while I was writing The CDA Book, I was putting in 70 - 80 hour weeks, and in the last month, about 80-100 hour weeks.   Total page count is around 400, so that works out to about 2.5 hours a page.  If I sell as many as I hope to, it would work out to about $20/hr after expenses.  If I sell as many copies as I expect to, it would work out to about $8.5/hr after expenses.  This is not a get rich quick scheme by any means.  I could do better answering this ad.

This was an interesting investigation because  I'm considering taking on another book project.  Metrics are great.  It gives me some targets for improvement.  The next book would be about using IHE profiles to create Health Information Exchange.  It's got quite a different audience I think, than the CDA Book, but I'm still exploring the idea, even this rate of return.  It's fun, but then again, I have a strange idea about fun.  Just ask my kids.  I have a book project to work with them on as well.  I think it'll start as a blog but be designed for eventual publication as a book.  The working title of that project is "Math you aren't supposed to Know".

Friday, December 31, 2010

What will we do with IT?

While others are thinking hard about how to make Healthcare IT better with new stuff, I'm thinking about how we can take what we've started with and use it in more interesting ways.  As David Tao points out, we are about to open the fire hoses with patient data here in the US.

According to NCHS Survey data for 2007 there were more than 1.2 billion visits to office based physicians, emergency rooms, out patient centers (pdf), and hospital stays.  If 1 in 5 providers attain meaningful use next year, and assuming that accounts for 20% of visits and hospital stays (which is probably undercounting), that gives 240 million visits for which a summary document should be able to be generated.  If even 5% of those visits generate a summary of care document using the HITSP C32, that will generate 12 million documents.  Most organizations I would expect will not even bother to ask, but will simply generate those documents.  At the very minumum, I would estimate that there will be something like 100 million summary documents floating around.  This is not a huge amount in the era of Google, but still quite a bit of data.  I personally expect an order or two of magnitude more than that.

What will we do with all of this data?
  1. Read it.
  2. Chart it.
  3. Index it.
  4. Normalize it.
  5. Measure it.
  6. Reduce it.
  7. Expand it.
  8. Merge it.
  9. Split it.
  10. Dashboard it.
  11. Evaluate it.
  12. Secure it.
  13. Store it.
  14. Anonymize it.
  15. Sell it?
  16. Buy it?
What IT do we need to deal with it?  This is a HUGE opportunity for research and innovation.  What will we do with it?

Thursday, December 9, 2010

CCHIT needs to follow test procedures for Certification

This showed up in my e-mail, but blogger marked it as spam, so I'm reposting it here.

Amit Trivedi has left a new comment on your post "CCHIT needs to follow test procedures for Certific...":

Keith – just want to set the facts straight. Our CCHIT Certified® testing requirements and the ONC-ATCB testing requirements are separate and distinct. We make it very clear to everyone that CCHIT uses the NIST test tools in its ONC-authorized certification program. We do *not* use the Laika tool for ONC-ATCB testing. We use the following tool as specified in the NIST test procedures for CCD/C32 validation: http://xreg2.nist.gov/cda-validation/mu.html

Your blog is well-read and we appreciate the work you do in the health IT standards community. We hope you will feel free to contact CCHIT directly to verify misstated claims such as this one.
Now for mea-culpas.  Yes, I should have checked in with CCHIT on this, and for failing to do that I apologize. 

On the flip side, CCHIT shouldn't be setting different requirements for Comprehensive Certification that CONFLICT with ONC-ATCB Certification, which is what appears to have done.  If it were me, I'd pick one tool and stick with it, but they could still use the LAIKA tool -- just update it to integrate with the RIGHT set of rules from NIST.


See comments below for updates. This may result from confusion between CCHIT Comprehensive certification (for which CCHIT can use their own procedures), and ONC-ATCB certification. In that case, comprehensive certification under CCHIT would seem to require something different from ONC-ATCB certification, which would certainly be unfortunate and undesirable, but not against the regulations.


Due to a technical problem, blogger lost the original content of this post.  I have reconstructed it below:


A recent post to the structured documents and CCD lists brings up the issue that the LAIKA tool isn't coming up with the same results as the NIST tools.  The LAIKA tool is wrong, and the NIST tool is right (click on the link above for details).

Under the applicable regulations [emphasis mine]:
§170.423 Principles of proper conduct for ONC-ATCBs.
...
(e) Use test tools and test procedures approved by the National Coordinator for the purposes of assessing Complete EHRs and/or EHR Modules compliance with the certification criteria adopted by the Secretary;

To my knowledge, only the NIST test procedures have been adopted by the secretary.  Those procedures  (pdf) reference the NIST test tool, not the LAIKA one.


Reading further in the Certification rule,

§170.560 Good standing as an ONC-ACB.
(a) Adhering to the Principles of Proper Conduct for ONC-ACBs;e.g., use procedures adopted by ONC...

So, going further, what's your recourse if affected?  A section down describes what ONC can do on recieving evidence of non-complaince.


§170.565 Revocation of authorized certification body status.
...
(b) Type-2 violations. The National Coordinator may revoke an ONC-ACB’s status for failing to timely or adequately correct a Type-2 violation. Type-2 violations comprise noncompliance with §170.560.

(1) Noncompliance notification. If the National Coordinator obtains reliable evidence that an ONC-ACB may no longer be in compliance with §170.560, the National Coordinator will issue a noncompliance notification with reasons for the notification to the ONC-ACB requesting that the ONC-ACB respond to the alleged violation and correct the violation, if applicable.


So, if you can show to ONC that CCHIT requires a testing procedure that is not the one accepted by ONC, you can almost certainly get CCHIT to fix it if ONC agrees that the procedure is in violation.