Showing posts with label Templates. Show all posts
Showing posts with label Templates. Show all posts

Friday, March 25, 2016

I really think we should ... Oh look, squirrel

So the question came up last working group meeting about whether to pursue use of the FHIR StructureDefinition as a mechanism to capture CDA Templates in some meeting somewhere.  I wasn't at that meeting or I would have shown my distaste for the idea then.  Grahame's been playing with StructureDefinition and has demonstrated quite successfully I think that he can use it to represent models for everything from HL7 Version 3, CDA (being a version 3 derived spec, that should be no surprise), to I would guess, V2, X12 and even arbitrary XML schema and other models provided they follow a few fairly simple rules.

Thus, I introduce to you the squirrel in question.  It's a cute squirrel, and even a rather powerful one.

Why do we need this?  We have a perfectly good standard for representing CDA templates if we would just use it in the tools HL7 presently uses to publish so much of its own documentation in.

But it isn't FHIR related, and loses to the flavor of the month (year? decade?) I think.  I suspect chasing this squirrel will only distract any further work on something else that might benefit the HL7 community at large ... for example, liberating CDA Templates from Trifolia in a standard format.

The only benefit I see to this distraction may have is to keep people tied up in a harmless activity, at least for anyone but the squirrel.  But I think StructureDefinition will survive that race.

   Keith

Monday, July 22, 2013

Bring on the Accessories

We are all fairly familiar with products that are designed for use with other products.  My favorite iPad accessory most recently was a car we rented while I was on vacation in England.  Essentially, the iPad recognized the car as an accessory iPod appliance that would allow me to play music through the radio, and could also integrate (if I used my iPhone) with the car's hands-free system.

In fact, sometimes it is the existence of the these accessories that makes us want the original product that it works with.

It's another IHE week in Oak Brook, and we are talking about CDA templates quite a bit, as we usually do in PCC Committee meetings.  At one particular point, one of the committee members, and I can't remember who, but I have a few suspicions, made the point that we should start thinking about designing templates to fit into different places, e.g., the accessories that go with the original system.  The idea was that this disconnected the document, or section or whatever you were creating the template to fit into from every having to know about the template in the first place.

This evolves into a comment I expect to make in the future HL7 templates ballot on metadata necessary for a template to support this kind of adaptation.  Because in many cases, a template should tell you where it works best, rather than the thing that might actually benefit from its existence.

I repeatedly get requests from friends and standards colleagues about this group or that group not making templates that support "our requirements", and looking for my assistance in bringing those requirements up.  But that isn't my specialty, or my need, and while I'm willing to consider these requests, I do have to focus on where the demand is.  Consider:  Would you complain to mega-corp about your special niche need not being supported in their latest and greatest iThingyMaBob   Or would you instead work on your own cool accessory that worked with the iThingyMaBob's published interface or developer kit, and made it able to support your niche's accessory?  If the iThingyMaBob is so cool, go for it, build your accessory, and if the world needs it, why you already work with it in the most popular ThingyMaBob out there, all they need to do is acquire your accessory.

This goes back in some ways to the discussion earlier this year about Context Sensitive Templates.  The key piece here is that your "accessory template" is adding features to an existing template (or collection of templates), to support some context sensitive behavior.  Designed well, this can be very powerful, and is reminiscent of the Decorator design pattern.

Done well, your template can provide capabilities such as employment/work history, or support for dietary specialties, as a couple of examples.  This would work for any niche for which you could probably create demand for an accessory, but not for an entire niche focused product.  After all, who would buy a combination phone/EKG device?  A rather small market, and propably not one who would do phones all that well, but they might make a great EKG. So, leave the phones to the folks that want to build em, and bring on the accessories.

And so my comment on template metadata is to ensure that in it there is a way for templates to communicate how they can connect, and to declare the ways in which they do so, so that the accessories aren't just useful, but decorative as well.


Friday, May 31, 2013

Progress on CDA Harmonization



Everything always talks longer than you want.  The above diagram went into the minutes of our May IHE face to face meeting, courtesy of XDCD.  I'm spending a good bit of time on this project, in the expectation that we will be able to shave huge chunks of time from developing IHE profiles.  That makes it worthwhile.

My target for the next week is to simply be able to perform a comparison of section requirements between the CDA Consolidation guide and the IHE PCC Technical Framework.  Fortunately, IHE and CCDA both chunk at a fairly high level, generating requirements about code, title, and a few other section attributes, and spend most of their time on subsection or entry requirements.

So after cleaning up the crosswalk (I found some missing templates in the appendix mapping CCDA templates to HITSP/IHE/HL7/CCD templates), I'm about ready to generate the requirements from the IHE and CCDA content.  This should go fairly quickly, because there are only about 28 templates that we need to do this for.

What I find most interesting is that the Consolidated CDA has 7 templates which it provides both "coded" and "uncoded" forms, and IHE PCC has 3, and they don't overlap.  It doesn't stop me from performing the comparison, but does mean that I'll have to perform ten comparisons twice, once against the "uncoded" form, and a second time against the coded form.  In performing these comparisons, I feel as if I'm trying to solve the graph isomorphism problem.  In one way, I am, but in another way I'm not.  We already have an evaluation of the isomorphism in the mappings between templates.  What I'm really trying to generate is how different these two graphs are.

In any case, I'm making progress, and given how much time I expect it to save, I still have several months of effort I can focus on this problem for it to be worthwhile.  At least according to Randall in his chart above.

Monday, May 13, 2013

Minimum Necessary and Open Templates

Last week at the HL7 Working Group Meeting, I taught a class on Templated CDA.  This is a class for implementation guide developers.  You might think it applies only to the kinds of folk who go to IHE or HL7 meetings, or perhaps S&I Framework or Canadian Standards collaborative meetings, but you might be surprised.  I define "implementation guide" rather broadly.  There are implementation guides that are defined at a national level (such as in the US Meaningful Use regulations), those defined at a regional or project level (such as those defined for Healtheway), and then there are those that are included with commercial products (we call those product manuals), or which are part of an organizations internal design documentation.  The use of these documents might differ, but the kinds of content it needs to contain, and the various choices that a specification editor has about what could be done are about the same.

One of the interesting topics of discussion in the class was on the use of Open vs. Closed templates.  An open template allows anything beyond what has been explicitly prohibited in the rules expressing the template.  A closed template prohibits anything beyond what has been explicitly allowed by the rules of the template.  The former is extensible and reusable.  The latter is not.  However, the latter is quite useful in cases where minimum necessary comes into play.  This is a key phrase that shows up in various places in US regulation to mean "no more than is needed" to serve a particular purpose.  Under HIPAA, exchange of information for payment or operations falls under the rubric of "minimum necessary".  However, exchanges for treatment do not (which doesn't stop people from trying to address them as if it were a requirement).

In public health, the use of minimum necessary in exchanges also facilitates risk mitigation.  If you know that users are only communicating the minimum necessary to support a particular public health function, you can address data risks using that minimum necessary criteria.

I really don't like letting an operational requirement cross over into the data models that we use to express template content.  Basically, it means to adopt the data model for a particular use case, I also get stuck with this additional piece of baggage (minimum necessary) that gets in the way of reuse.  My recommendation to my students is to define their templates in "open" terms, and then define the characteristics of the systems that exchange them as being able to, or unable to accept open content during an exchange.

So, now I have my cake (an open template), and other systems can define how they want to eat it (with or without any additional toppings).

Friday, May 10, 2013

Versioning Templates in Definitions and Instances

We had a great discussion this morning in the Templates workgroup.  One of the agreements that we came pretty close to making was how to address referencing a templateId in an instance when you are dealing with old-style (version-unaware) templates, and new-style (version aware) templates.

In the old way, this was the correct way to reference a template.
<templateId root='1.2.3.5'/>

In the new way, this is the correct way to reference a specific version of the template.
<templateId root='1.2.3.5' extension='versionLabel'/>

When operating under the old world order, and in the new world order, the first reference to a template identifer in an instance still needs to work.

That's because instances created using version aware templates may still need to refer to other templates that aren't yet version aware (under the new model).

So, the first example above is what I'm calling a version unaware templateId, and the second example is a version aware templateId.  The former can only point to a version unaware template definition, and the latter can only point to a version aware template definition.

Instances can use either or both forms.  And in fact, this is perfectly legal:

<act>
  <templateId root='1.2.3.5'/>
  <templateId root='1.2.3.5' extension='versionLabel'/>
   ...
</act>

In the example above, the instance of the act is declaring conformance to both the version unaware release of the template, and to the newer version aware edition.

The Art-Decor project currenly uses <templateId root='1.2.3.5'> to reference "the current version" of the template, enforcing a "dynamic" constraint to the template.  I would argue that any content creator knows WHICH version(s) of a template are being used, and so MUST report the version identifier.  That is because versions are allowed to introduce backwards incompatible changes (which is part of why we doing this).

In any case, we will be discussing this further next week.


Tuesday, March 19, 2013

Negotiating the Protocol

I'm in Treviso, Italy this week for IHE meetings.  As always, when I'm in a country that speaks a language other than my own, I make an attempt to use what I know of the language in speaking to others, at least for greeting them.  However, I noted that in both Italy, and when I was in Paris previously, my greetings were inevitably responded to in English when the speaker was able to use that language.

The protocol the listener used to fall-back to English was fairly straightforward.  They detected something in my accent that made it clear to them that I was not a native speaker.  In the case of Italian, it was my failure to prounounce buon giorno correctly.  I was missing the initial DJ sound in giorno (pronouncing it with a softer J sound), and failing to roll my R's (a failing that caused me great problems in my high school Italian class as well).

In IHE PCC, we are working on creating version aware templates as part of our ongoing work on harmonization with the Consolidated CDA.  One of the things that developers routinely ask me for is how they can tell what set of templates are used in a document.  This is especially important in the context of versioned templates.  In this case, a developer wants to know if it is even worth their time to process a document that may contain something they don't understand.

The solution that we finally came upon is quite similar to what a Java compiler does when it creates class file.  You can tell the compiler to create a class file that works with a particular version of a JVM.  Newer JVM's can process class files that were compiled for older ones, but if an older JVM encounters a class file that reports itself as being built for a newer JVM, it will refuse to load it.  We will enable such marking in the TF.

A content creator of a CDA document that is produced using templates from the PCC Technical Framework has a responsibility to mark the minimum version of the Technical Framework that is required to be understood.  This mark will appear in a <templateId> element appearing in the header.  Presence of that identifier is an indicator to the receiver that if they do not understand templates in that revision of the technical framework, they might not be able to understand the content of the document.  It's not an absolute statement that they won't work, just a warning that they may not work.  To parallel with the Java case, there are new structures and/or JVM operations that may appear in the class file, that older JVMs will not understand.

In this fashion, a receiver of content can examine the <templateId> associated with TF version.  It can then take appropriate actions based on the root and extension values found, and as necessary (as with me to an Italian speaker), fall back to something that both parties understand, or indicate that it cannot understand the content, or determine that it will try to understand anyway (much more like my wife), and only when it fails to understand, abandon the conversation.

To actually be able to (safely) understand something even though it is written to a later version of the technical framework than the system is designed for is built into how we mark versions.  Templates have a major and minor version number.  The major number changes when the new template cannot be understood (safely) by a system designed to understand a previous version.  Only the minor number changes when the template changes in a way that is backwards compatible, and only adds new information.

The intent of the distinctions we have created for major and minor change is to address issues of correct interpretations and thus patient safety in those interpretation of exchanged content.  However, I use the term (safely) in parenthesis above, because there is no way for IHE to determine what consumers can do with exchanged content safely. We can simply advise that something may not be safe (which the major/minor change distinction does).  It is, and must always be up to individual products to determine what is safe for patients based on their existing risk assessment processes.



Monday, February 25, 2013

I don't care what it is called, tell me what it is!

With nearly three decades of experience writing software, I can tell you that I no longer worry about the names of things nearly so much as I used to.  In my early days, we'd put the names into the product, and almost like clockwork, marketing would change the product name weeks or even days before release of the final (planned) build to QA.  Inevitably, search and replace would fail producing a nonsense phrase, and/or someone would report a bug about bad text wrapping somewhere, or even worse, nobody would spot the problem caused by the name change.

As I grew more experienced, we'd slug the name AND reserve more than the expected amount of space for it in the UI, and design for the inevitable change (or two).  And I'd refuse to put the current name of the product in until Marketing had a) signed off on the product name, and b) spent their own money producing marketing literature using it.  In which case, I felt safe enough to go forward with it.

These days, I'm much more concerned with understanding what it is, rather than what you call it.  I know how to describe something using numerous different names.  There are names that engineers recognize, and other names for architects, and yet others names for marketers and C-levels.  The key is not in naming, but in describing what it is in a way that your audience will understand it.

Case in point: Archetype, Template and Detailed Clinical Model.  Explain the difference between these.  The way I do it for a CEO is fairly straightforward.  These are all essentially the same thing.  The way I do it for practitioners of these black arts is much different.  It's like explaining the difference between cancer, melanoma and tumor to people with various levels of medical understanding.

Yes, the fine details matter.  But only to SOME audiences.

-- Keith


Wednesday, October 17, 2012

Versioning Templates

In IHE and HL7, we've been using the <templateId> element to identify templates.  One of the challenges has been that creating a new version of a template changes the requirements of any templates that use that template.  Consider the case where an implementation guide has two templates, template A, and template B, and template A says: must contain [n..m] instances of template B.  Making a substantive change to the content of template B means that it must have a new identifier.  We'll use B' in this case.

So now, template A must say: must contain [n..m] instances of template B'.  But this too is a substantive change to template A, and so template A must be given a new identifier (template A').  And so the change propagates upwards through the entire document.  This may be desirable in some cases, but in others, it totally sucks.

When we started with template identifiers in HL7, we did something this:

<templateId root="2.16.840.1.113883.10" 
  extension="IMPL_CDAR2_LEVEL1-2REF_US_I2_2005SEP" />


Later, we shifted to this form:
<templateId root='2.16.840.1.113883.10.20.1'/>

Dropping the extension attribute, and just uniquely identifying the template with the root attribute.

Some have suggested going back to using the extension attribute, but using it to represent the "version" of the template.  Originally, I thought this was a bad idea, because it semantically overloads the extension attribute.  I've changed my mind somewhat, because this is a useful a convention, or best practice, rather than semantics.  What we are doing is saying that: root represents an identifier for the the concept expressed by the template, and extension represents different ways (versions) that this concept can be expressed.

Using versions, we can write templates a bit differently.  Consider our template A above.  Suppose we had written it instead as template A: must contain [n..m] instances of templates whose root is B.root.  Now, when we create a new version of B, B.root will remain the same (because the template expresses the same context), but B.extension will be different.  We could also fix to a particular version, as in:  A must contain [n..m] instances of template whose root is B.root and whose version is B.extension.  Or we could set a lower bound on the version of the template.

Ideally, data types would allow template identifiers to support versioning, just as code systems and value sets can be versioned, but it doesn't.  So, we can make a gentleperson's agreement to deal with root and extension in this fashion.

A disadvantage of this scheme is that a system that only knows how to address version 1.0 the content of template B, won't know what to do with version 2.0 when it encounters it.  Furthermore, it can no longer just look at the document template to see whether it knows how to deal with all of the templates inside of it.  So, you'd need to look at more than just the document template to understand whether you can deal with all of the content.

I've got some thoughts on how to generate a CDA document that uses two different versions of (wire-format incompatible) templates, but I'll save that for tomorrow.


Friday, April 20, 2012

Forward Compatibility and the use of Templates with HL7 CDA

I had an interesting conversation with Wes Rishel this afternoon regarding his post on "Frozen Interface Syndrome" in which he talks about bilateral asynchronous cut-over.  He brings up an excellent point, which is that there need to be principles in the development and revision of standards in which we enable compatibility at the same time as we allow for advancement, to avoid freezing interfaces.

There's a phrase used in standards development that talks about backwards compatibility.  A standard is said to be backwards compatible when it enables all features of the previous version to be represented in the new version.  This ensured that there would be a smooth transition from one version of the standard to the next because it ensures that functionality is maintained across versions.  But it is insufficient to allow for bilateral asynchronous cut-over.  To do that, we need to design for foward compatibility.

Templated CDA goes a step further because there are ways to develop standards that ensure that:

  1. Systems expecting content formatted according to a new version of the standard can layer functionality to downgrade gracefully upon receipt of content formatted according to the old version. 
  2. Systems expecting content formatted according to the old version of the standard can understand what to do upon receipt of content formatted according to the new version.
Each template identifier asserted by a component of a CDA document is immutable with respect to compatibility breaking changes, by agreement of HL7 Workgroups.  I expect this principal will be formalized in the next version of the HL7 Templates standard.  It is one that has been followed routinely for the past half-decade by HL7, IHE, HITSP, epSOS and other organizations developing templates for CDA and HL7 Version 3 messages.

This has some challenges, because if you make a compatibility breaking change in template X producing X.1, and template Y requires X, and template Z requires Y, then you must also change the identifiers of templates Y and Z to enforce the use of X.1 instead of X.

To give a concrete example, CCDA presently says that an Allergy template may contain a severity template.  Let us suppose that healthcare has advanced to the point that we are ready to say that severity SHALL be provided with all allergies.  At that point, we want to say that the Allergy section requires the new allergy template with the required severity, and so this becomes a "compatibility-breaking" requirement on the old section, and so must also be assigned a new identifier.  And any document that wants to require that new section also breaks backward compatibilty, and so requires a new identifier.

But a system that understands the old allergy template should also be able to understand the new one.  And it will also be able to understand the new section and the new document template. The problem is that it was never designed to know about these new templates.  And so we must tell it that the content it receives also conforms to the older template structure.   We would do that by asserting conformance to both the old and the new templates.

One would hope that we could take advantage of this notion of forward compatibility as much as possible in all future development of CDA templates, as it provides a mechanism to allow for bilateral asynchronous cutover that Wes and I would both find desirable.  You'll note that these principles are already enabled via the incremental interoperability that HITSP and IHE used by layering new templates over existing HL7 templates providing varying degrees of interoperability.   

I'll note that this mechanism does not address is the situation we are in today with regard to HITSP C32 Version 2.5 and its use of CCD 1.0, vs. the Consolidated CDA description of CCD 1.1.  In that case, we can apply forwards compatibility in most, but not all cases.  Due to limitations in existing care provision models at the time that CCD 1.0 was created, and their current state when CCD 1.1 was created, there are some templates that just aren't compatible between versions.  There are transforms that can be applied to enable compatibility for many of the exception cases (I won't say all yet, because I haven't finished my analysis).  I'll address how to do that when I get more time to focus on my Changing from HITSP C32 Version 2.5 to Consolidated CDA post.

In future versions of the Consolidated CDA guide, I expect similar situations to be quite rarely encountered, and so HL7 should be able to ensure forward compatibility in subsequent editions with little challenges.

On a final note, at the very least, when receiving a CDA, even one which an application doesn't know to interpret, every application should be able to display it.  That provides at least a base level of interoperability between systems that should be present with just about every CDA implementation.

  -- Keith

P.S.  You'll note that I have yet to catch on to using the acronym CCDA for Consolidated CDA, but I recently noted that it does put the CCD back together with CDA, and so maybe I will adopt it.  I just don't know how I feel about that yet.  What do you think?

Tuesday, March 6, 2012

Liberating Consolidated CDA Templates from the Trifolia Workbench Data

One of the major promises of the CDA Consolidation project is the ability to automate the creation of validation and development tools from the model driven data for the templates.  I had hoped that there would be stronger collaboration MDHT project, and eventually I expect that will happen.  A few weeks back, HL7 and Lantana released a copy of the Trifolia Workbench (pdf) with the CDA Consolidation data (zip).  Trifolia Workbench is released under the Eclipse Public License. Source code, as it stands today is the database schema, and a Microsoft Access front end, along with tools to load a MySQL database with the data from the CDA Consolidation guide.

As far as tools go, it's a start, but I need more.  My developers want a Schematron for the CDA Consolidation Guide.  I want the data in a format that I can compare with the source materials to perform a gap analysis with the HITSP C32.  So, I took a break over the last two days to work on getting the data into a format that I can use it (XML), and started building a Schematron from it.  The first part works very well and you can find it under the Download heading below.  The second is still a work in progress, so I won't make it available today.

To get the data out of the database into an XML Format, I used three tools:  
Oxygen includes Xalan, and that includes a SQL Extensions library, which means that I can perform  queries to unlock the data in the Trifolia Workbench tables.  I wrote a two pass transform where the first pass rips the tables, and the second pass builds the appropriate XML structure.  The Trifolia template database has five main tables:
  • Templates (template)
  • Constraints (template_constraint)
  • Code Systems (dictionarycodesystem)
  • Value Sets (valueset)
  • Value Set Members (valuesetmember)
The first two main tables are the most important from a validation perspective.  The remaining three support simple value set maintenance.  There are also a number of code tables containing human readable terms for various purposes:
  • Vocabulary Binding Types (vocbinding_type) [STATIC, DYNAMIC]
  • Contexts (dictionarycontext)
  • Conformance Types (conformance_type) [SHALL, SHALL NOT, SHOULD, SHOULD NOT, MAY]
  • Template Types (template_type) [document, section, entry, subentry, unspecified]
I don't deal with the implementation guide tables (implementationguide or associationtemplateimplementationguide), or the list of users (tdb_users), but you should know these tables are there.

In the first pass, the contents of these tables are copied into <templates>, <constraints>, <codeSystems>, <valueSets>, and <members> elements inside the <tdb> element.  Copying the data is pretty straightforward.  The first step is to perform the appropriate query against the tables, resolving  terms in the code tables with LEFT JOIN operations.

I wrote a template that processes the result set, and generates and attribute or element for each cell in each row using the column labels.  I reproduce it below because it can be used to liberate data from any SQL query in an XML format.

  <xsl:template name="SQLtoXML">
    <!-- resultXML is the rowset returned by the query -->
    <xsl:param name="resultXML" select="."/>
    <xsl:param name="result" select="exslt:node-set($resultXML)"/>
    <!-- map is a string containing either an a or an e for each cell
         indicating whether it should be output as an attribute or an
         element
    -->
    <xsl:param name="map"/>
    <xsl:param name="meta" select="$result/sql/metadata"/>

    <!-- name is the element name to use for each row, and defaults
         to the table name -->
    <xsl:param name="name" select="$meta/column-header[1]/@table-name"/>

    <!-- for each row in the result set -->
    <xsl:for-each select="$result/sql/row-set/row">
      <!-- generate an element for the row -->
      <xsl:element name="{$name}">
        <!-- for each column in the result set -->
        <xsl:for-each select="col">
          <xsl:variable name="pos" select="position()"/>
          <!-- if there is an a in the map position for the cell -->
          <xsl:if
            test="substring($map, $pos, 1) = 'a' and string(.) != ''">
            <!-- generate an attribute for it -->
            <xsl:attribute name="{@column-label}">
              <xsl:value-of select="."/>
            </xsl:attribute>
          </xsl:if>
        </xsl:for-each>
        <!-- And again for each column in the result set -->
        <xsl:for-each select="col">
          <xsl:variable name="pos" select="position()"/>
          <!-- if there is an e in the map position for the cell -->
          <xsl:if
            test="substring($map, $pos, 1) != 'a' and string(.) != ''">
            <!-- generate an element for it -->
            <xsl:element name="{@column-label}">
              <xsl:value-of select="."/>
            </xsl:element>
          </xsl:if>
        </xsl:for-each>
      </xsl:element>
    </xsl:for-each>
  </xsl:template> 

The first pass extracts the data to an XML Fragment, but the appropriate containment isn't established.  That fragment is restructured in the second pass.  In that pass, each constraint element is placed inside the appropriate <template> or <constraint> depending upon its parentConstraintID and templateID attributes, and each <member> is inserted inside the appropriate <valueSet> element based upon it's valueSetOID attribute (see notes below).

Ripping the data out took about half a day, and the XML format is remarkably close to what I suggested as a metamodel not quite a year ago. The next step is crafting a Schematron from this.  I've gotten that nearly working, but have to work around this notion of branches that is in Trifolia.  If I had a notion of what MDHT wanted as an import format for templates, I could also produce that.

Download
You can download the Stylesheet from Google Code.  It extracts the data from the Trifolia Workbench database into an XML Format.  Document on that format will come as soon as I'm happy with it.

Instructions
  1. Install the Trifolia Database according to the Instructions (requires MySQL Community Edition)
    Note: If MySQL is already installed, be sure to execute the set charset latin1 command before running the source command.
  2. Install the JDBC Driver for MySQL.  Copy the jar file to the appropriate lib folder.
  3. Modify the <xsl:param> elements at the top of the stylesheet to insert your user and password for creating the database connection.
  4. Run the stylesheet.  It will output a file containing the contents of the template database.
Issues and Questions
If you have issues or questions, please add comments below.  I'll do my best to address them here.

Notes
The stylesheet fixes up a couple of problems in the Trifolia Workbench data.  Contexts in the workbench data aren't namespace qualified, so you cannot use them directly in stylesheets or Schematron.  I've patched that for now in the stylesheet, and logged a bug to the Lantana JIRA Bug tracker via this e-mail (only use this e-mail to report bugs in the Trifolia Workbench).

Also, be aware that the valueSetOID field in template_constraint is actually the ID of the value set, not it's OID.  I patched that to in my stylesheet, and logged a separate bug for that.

Wednesday, June 29, 2011

Comments, Code or Both

What belongs in an implementation guide?  Many HL7 implementation guides and  IHE profiles include the requirements of an implementation, sometimes with an explanation of the more tricky bits.  On a discussion today, someone asked (or at least I thought they did) about the separation of content between documentation stuff and functional requirements with respect to the template meta-Model.

I responded thus:

It's like code.  When I'm doing a code review, if a comment in the code is wrong, the code is wrong, even if the comment doesn't functionally contribute to the execution.  That's because it does contribute to the maintenance of the code it comments on.  So, I don't see a need to keep them separate, and I do in fact see a need to keep descriptive, "non-normative" stuff together with the stuff that allows systems to validate or implement the templates.

The point being that the "non-normative" stuff is what helps implementers do stuff, and it needs to be kept together, even if it doesn't help in code generation.

Wednesday, May 11, 2011

Idioms as insight into Models - A synthesis across Templates and CDS models

Software developers use programming languages in idiomatic ways all the time.  The infamous "endless" loop in C/C++ looks like this:

for(;;)
{
}

Most programmers will learn to recognize these common idioms and move on.  Sometimes the idiomatic use so simple that it never needs to be codified, and is easily understood (like the endless loop above).  At other times, the idiom is rather complicated and in some ways, inexplicable.

Here is an example from XSLT.  See if you can figure out what it does before I explain it:

substring-before(concat(translate(X,'+','-'),'-'),'-')

This particular idiom is one I use regularly.  For a string X, it first translates any occurrence of '+' into a '-'.  Then it appends a '-' to the string.  Then it extracts whatever string appears before the '-' character. If X is an ISO 8601 formatted date-timestamp with an optional time zone, this expression will extract just the date-timestamp portion of it without the timezone.

Language developers will often take common idioms and use them to develop new language features that re-implement the idiomatic usage.  If I were writing an XSLT library, I'd certainly put in some timestamp manipulation functions to avoid having to write this in its idiomatic (and idiotic) form.

Idioms are important because they identify common patterns of use.  In looking over a number of templates in IHE, HL7 and HITSP, and identified a bakers dozen of common idioms.  From that, and a review of the documentation, we have enough information to put together a template meta-model.

Earlier today I was on a call talking about clinical decision support and GELLO.  GELLO has to be my least favorite language for expressing things in a clear form. It shares a common feature with XSLT which is that it is declarative.  Declarative programming is counter-intuitive for most people when the first encounter it.  SQL is also a declarative programming language.  The benefit of declarative programming languages is that they specify what the result looks like, not how to generate it, or the order of the steps needed to accomplish the task.  The counter-intuitive part is that you have to think "backwards" and "upside-down" or "inside-out" and forget procedures.  It takes a while to learn that skill (or at least it did for me).

One of the pieces of feedback that the speaker had gotten about GELLO was the love/hate, and mostly hate relationship that non-technical people had with GELLO when examining clinical decision support rules.  I feel almost the same way about OCL as I do about GELLO, which isn't surprising since GELLO is derived from OCL (and should become a proper subset of it some day).

Having recently had a similar experience with OCL (because MDHT expresses constraints in OCL), and having figured out that the idioms used are a key to figuring out the meta-model, what I realized was that the same was also true in Clinical Decision Support.  The idioms used in clinical decision support are what will be important to providers when we finally figure out what it's meta-model is.  For Templates, we had to get to over a hundred of them before I could see (and use) common idioms.  Having over 1000, I'm pretty certain we have all the key ones nailed down.  I suspect we'll need to do the same for Clinical Decision Support.

There's still some odd-ball stuff that we'd have to represent directly for templates in a "low-level" construct like Schematron/XPath or OCL.  We can live with that.  After all, sometimes you need to call into an assembly language routine from a high level language too.  I'm certain the same will be true for clinical decision support as well.

As I think about this even more, I'm struck by yet another similarity.  High level languages (and from them Object-oriented languages) originated from assembly.  If you think of GELLO or Schematron as the assembly language, you can see where models and high level languages for templates (or CDS) will finally emerge.

I love it when separate activities come together like this.

Friday, April 29, 2011

A Template Meta-model

-- And miles to go before I sleep.      Robert Frost "Stopping by Woods on a Snowy Evening" 
When I have a really difficult task to finish that my brain is not ready to work on (some would call it writer's block), I try to work around it by looking at related stuff.  I'm now into the analysis phase on the CDA Consolidation ballot (which I have to have a draft of by Wednesday).  But I'm still struggling, so I finished a quick analysis of HL7, Health Story, IHE and HITSP specifications to come up with a document model this evening.  I also looked at previous work from the HL7 Templates workgroup, including the Template Registry Requirements, and the data model I had proposed for a pilot registry project that I was never able to finish for lack of time and assistance.  It went quicker than I thought it would, but since I've been paying attention to templates from these organizations for the past five years, perhaps I shouldn't be surprised.

Let's start with the document model first.

An implementation guide has a title page, table of contents, front matter, a body and back matter.  I focused all my attention on the body.  Within the body there are 4 different kinds of templates which are commonly organized around the CDA Header, the CDA Document, Sections and Entries.  Document and section templates are very easy to analyze, and fit into the same general structure.  It turns out that header and entry templates are very similar as well.

Included in the analysis are my opinions, which appear in italics.


I hereby contribute the remainder of this post to the public domain.

Template
Template Name
This is a short human readable name that quickly describes the template.  It's for human readability.  Changing the name of a template DOES NOT affect its use.
Identifier
This is a single identifier that must be present and is always valued.  HL7, IHE and HITSP all recommend use of an OID as the identifier, with no extension, and so do I.  My first CDA template used extensions, and I've seen several that do also.  It's not a show-stopper either way.
Open or Closed Status
If a template is open, everything not explicitly prohibited is allowed.  If closed, everything not explicitly allowed is prohibited.  This is USUALLY the same for all templates within an implementation guide.  As such, it could be documented in the front matter rather than with each general template.  The current model for the CDA Consolidation guide is to explicitly document it for each template.  I find that extra "gunge" to be distracting, but not so much that I would object to making it available.

A closed template is like a "final" class in UML.  It can no longer be extended to support new use cases (although see implicit inheritance below).

In more than 1000 templates I've looked at or helped develop for CDA (yes, there are THAT many and I've looked at them), I've never seen ONE closed template that I can recall.  I know they exist, just not in the CDA universe .. kind of like anti-matter.   I don't like them because they interfere with reuse, just as I avoid "final" classes in Java. 

Parent Templates:
A template can inherit constraints from one or more parent templates.  HITSP uses multiple parents to harmonize across IHE and HL7 overlaps, and avoided it elsewhere.  IHE PCC uses inheritance from only one parent template.  A PCC template may have multiple ancestors, so there can still be multiple template identifiers.  Inheritance is optional.  A template need not have any parent templates.
I like the one template inheritance rule, but when you get to real-world implementation, it may need to be relaxed.  


  Parent Template ID:
    This is the identifier of the parent template.
  Explicit or Implicit Inheritance:
    This is a boolean flag indicating whether the inheritance must be explicitly expressed in the instance, or whether it is implied by template that inherits from the parent.  If implied, the template need not report its parents.  If explicit, then it must.  This allows reuse of sets of constraints in a template -- and introduces the idea that a template could also be abstract -- never directly instantiated without further constraint.  A closed template can only be inherited from implicitly, never explicitly.

When explicit inheritance is present, you have a couple of options in documentation:

  1. Copy the constraints from the parent template into the documentation of its child, indicating that template as the source
  2. Don't copy them, but do include a link to them from the child.  
IHE and HITSP used the latter model.  The CDA Consolidation guide uses the former.  

I like explicit inheritance because it enables incremental interoperability without having knowledge of the "inheritance" rules. The CDA Consolidation guide templates won't provide any incremental interoperability with epSOS work even if they shared the same constraints because the shared constraints aren't enumerated.  You could still build a document that enabled incremental interoperability by using them, but you don't "get it for free".


Scope:
Scope indicates where the template is applicable.  It can constrain where template may appear, or describe the scope of the use case where it is applicable.
  Scope Narrative:
    A narrative description of the scope.  It need not be present.
  Class: [1..*]
    The set of classes (model artifacts) to which the template applies (e.g., this template only applies to sections in CDA).

Description:
A narrative description that talks about the template.  This is commonly present in IHE and HITSP templates, and is missing from many of the CDA Consolidation templates.  I think this must be present for all templates, but could be argued into "should".
The narrative can include references to other important stuff in the documentation (much like the HL7 PubDB format allows today), including material not generated by a template development tool (e.g., like MDHT or TDB).

Model Diagram:
This is a diagram generated from the template model expressing the template in UML form.
Model Table:
This is a table describing the template using data in the template's model.  It too is machine generated.
Examples:
This is list containing at least one example of the template content.  Two forms are often used:  A skeletal example showing only what the template constrains, and a full example with additional stuff that shows the xml with sensible clinical data.

IHE and HITSP use a skeletal model.  Skeletons are very easy to generate using model data, and are also easy for non-clinical users to create manually (e.g., me).  Full examples that make clinical sense often need human assistance for sample values, et cetera.  Template development tools can support creation of full examples.

Examples really should be present for all but the most obvious stuff, and if you are someone like me, you cannot trust your own intuition about what is obvious.  If it can be machine generated, then why worry, just DO it.

Negative Examples:
Negative examples are helpful when there are obvious ways to mess things up.  They need to be clearly labeled as WRONG, BAD, et cetera.  One of the things I've learned is that the easiest way to show people how to not make the obvious mistake is to show them what it looks like.  It's how I went from this:

‹code›‹originalText›SARS‹/orginalText›‹/code›

to this:

‹code nullFlavor='UNK'›‹originalText›SARS‹/orginalText›‹/code›

Good bad examples are hard to automatically generate.  Tooling could help, but this might be a case where you'd just include external content.  Negative examples are only needed where you want to point out a problem case that isn't obvious.

Constraints:
A template has at least one, and usually more than one constraint (if none, there is no reason for it to exist).  Constraints are the next "reusable" object I found in the analysis.  These are the numbered things in the CDA Consolidation Guide.

Constraint
Identifier:
A constraint has an identifier that allows it to be referenced.  Constraints are reusable (IHE, HL7 and HITSP did it quite often), e.g. X shall be an interval of time contain a low/@value and a high/@value.
Target Component Name:

You need to identify what you are constraining, and most of the time it is only one element or attribute.  The component either a class attribute of the class being constrained by the template, a component of the data type of a class attribute, or an association with another class.  It could also go deeper.

This is where MDHT did not perform well that TDB did.  The "long list" of general header constraints produced by MDHT were a result of several issues, one of which this solves.  The other half of the solution has to do with guidelines (governance) about where to put template boundaries.  The template should begin and end within a single class, using other templates to enforce business rules on associated classes.  This rule can be broken in some cases because sometimes you may need to "go deep" just once, and you don't want to create extra templates just to enforce a rule.  The entryRelationship class in CDA uses three lines of XML.  Why would I want to create templates to say act X must contain entryRelationship Y and entryRelationship Y must contain act Z, when I could more simply say: act X must contain entryRelationship/act Z. 


Target Component Definition:
You often need to explain what the target component is used for.

This is what I've been doing for the recent Reconciliation profile in IHE, building from similar earlier work, and something that the CDA Consolidation guide did not do well.

Trigger Condition:
Sometimes a constraint is triggered by a pre-condition.  If trigger then constraint is a common pattern in several templates found in the CDA Consolidation guide.

Constraint: [0..*]
Constraints can have "sub-constraints" ... and those can have sub-constraints as well.
This is something that TDB does well.


Content Description [0..1]:
This is human readable text explaining what the constraint is doing.  It is needed when the effect of the constraint is not-obvious.  For example, the XPath representation of a constraint on effectiveTime/@value fixing the precision to be at least the second would look like this:


string-length(substring-after(translate(concat(@value,'+'),'-','+'),'+')) > 16

But the description can simply say: must be precise to the day.

For implementation purposes, I'd recommend use of ISO Schematron and XSLT 2.0 because then you can define functions for precision of dates which are simpler to read (at least I think you can).


Data Type Restriction [0..*]:
You might want to say that effectiveTime must always be an IVL_TS, or that code must be constrained to CE.  There need not be a data type restriction.  It might also be tricky, the substanceAdministration/effectiveTime, which IHE limited to [0..2].


Nullible: [0..1]
Can this item be null?  Yes or No.


Cardinality: [0..1]
What are the upper and lower bounds.  If unspecified, then the base model rules.


Conformance [1..1]:  Shall|Should|May|Shall Not|Should Not|Need Not
What is the conformance verb used?


Reason:
A text explanation of WHY the constraint is present.  What does it accomplish?  Why is it here?
Let's stop relying on our collective memories.  Frankly, over time, they aren't all that great (which isn't what I said before the second rewrite).

Precision:
If a QTY data type, what is the precision of it.  And TS is a quantity data type.


Value Set [0..1]:
If coded, what is the value set ... is another reusable artifact.


Value Set
Name:
What do we call this thing?
Identifier:
How does the computer identify it.
Scope:
What does it apply to?  This value set applies to procedures, encounters, lab results, et cetera.
Definition:  
X and all subordinate children from SNOMED CT ... or X, Y and Z, or a combination of these.
Purpose:  
Why does it exist?  What is it used for.
Intensional/Extensional:
How is it defined?  By an operational definition, or an explicit list.
Static or Dynamic:
Is it fixed to a specific vocabulary version, or can it change when a new version is release.
By the way: I really don't like it that we put static/dynamic in next to every value set in the conformance rules.  Static/dynamic are bindings that apply to the value set, not its use.  At least in my world.  I've never seen an implementation guide that would use static in one place for a value set, and dynamic in another.  It's just a REALLY BAD idea.  More gunge to ignore.

General Notes
From the work above, I can create a beautiful CDA Implementation Guide with rich multi-media, XML Schema for GreenXMI templates, a UML Meta-model for templates, or a MIF-based expression of templates.  I'm going to leave all of that in the hands of others.  I have to get back to my review the CDA Consolidation guide.  


What's not in here are the components of the meta-model important to governance and provenance.  That's great stuff, but not a requirement for MDHT to be able to do what we need yet. 


Having run through this excercise, I can now exchange my axe for a scalpel -- and when we go through reconciliation, I absolutely won't take an arbitrary deadline as an excuse for not doing it right.  It takes as much as it will take -- if you want quality, you have to give it time.


I don't know that I'm back to done yet, but I sure hope I'm getting things smart.  I have three more deliverables before Monday before I call myself done again.

Monday, January 10, 2011

Triplets

@motocycle_guy: @omowizard An archetype, a DCM and a template walk into an #HL7WGM event, stroll up to the bar ... and the bartender says...


@omowizard: @motorcycle_guy ...identical triplets I presume! #HL7WGM

Well, not quite identical, but certainly they share the same parents, intellectually at least.
 
From the HL7 Perspective:
A Detailed Clinical Model is an information model of a discrete set of precise clinical knowledge which can be used in a variety of contexts. (see the HL7 Conceptual Definition).

 
A Template is a collection of contraints that can be applied to a model [based on a pronouncement by LLoyd McKenzie at the last MnM/SDWG Meeting of the day, so it must be true ;-) ].  It's also defined in nearly the same words in the HL7 Templates DSTUA template is an expression of a set of constraints on the RIM or a RIM derived model that is used to apply additional constraints to a portion of an instance of data which is expressed in terms of some other Static Model.
 
Given that the HL7 process works via refinement on the RIM, a Detailed Clinical Model is a refinement of the RIM information model providing a discrete set of precise clinical knowledge...
 
Which makes it an expression of a set constraints on a RIM derived model, which makes it a template.
 
Now, quoting from the openEHR perspective (see page 8 of Archetype Definitions and Principles [pdf])
 
An archetype is a computable expression of a domain content model in the form of structured constraint statements, based on a reference (information) model.
 
And, a template is: a directly locally usable definition which composes archetypes into a larger structures often corresponding to a screen form, document, report or message. A templates may add further local constraints on the archetypes it mentions, including removing or mandating optional sections, and may define default values. 
 
But, an openEHR archetype is further specified: openEHR archetypes are based on the openEHR reference model.
 
So, an HL7 DCM is an archetype, but not an openEHR archetype because is derived from the HL7 Reference model rather than the openEHR reference model (and I think a blog post comparing the two is worth doing).
 
And an openEHR notion of a template is a collection of constrainsts on screen forms, documents, reports or messages, which means that it is a subset of HL7 templates.  What an openEHR template doesn't include are the set of constraints which make up the detailed clinical model (which HL7 could also express as a template).  These are what we would call document or section templates in HL7 or IHE, and the "DCMs" are what HL7 IHE would describe as a deeper refinement of "Entry Templates" on CDA.
 
The amount of precision in these fine distinctions is about as useful as trying to cut butter with a lazer.  It may be very precise, but all it really does is get in the way of breakfast.  But, as @omowizard points out, it didn't get in the way of dinner.
 
So, how do we take the collective intelligence of these two organizations forward.  I would propose a trial project covered by an MOU between the two organizations.  Let's have openEHR provide resources to help HL7 put together DCMs for some stuff, and then, using the outputs of that, have HL7 ballot the materials as a DSTU which would be shared content across both organizations.
 
That's liable to get me some strange looks in certain circles, especially back in some camps where openEHR isn't even mentioned and the great evil is that other XML perpetuated by yet another organization.
 
But what can I say?  We've already learned so much from CCD, let's give it another go.  After all, if the project fails, we've lost little, and if it succeeds ...

Friday, January 22, 2010

Template Registry

There were plenty more people here on Phoenix on Friday than usually. That's because Phoenix is having a major rainstorm, rather than there being a ton of great topics being discussed on this last day of the HL7 Working group meeting. However, there was one topic that I did especially stay for:

Templates Registry Pilot Kickoff

The Templates workgroup hosted a morning joint meeting with the Structured Documents, Patient Care and Vocabulary workgroups to kick off the Templates Registry Pilot project.  This project builds off the requirements that came from the Templates Registry Business Requirements project, which can be found in the HL7 Templates Registry GForge site.  We reviewed a slide deck descrfibing these requirements at a high level.

The rest of the meeting we spent going over what our first steps would be and started to put together a plan for the first few iterations of development.  A large number of people in the room volunteered to participate in various aspects of using the registry and designing some of the components, but we are still looking for resources to help with the development.

Iteration I will consist of a key design document on the registry metadata content, and development of one major component to support registration of templates and viewing of a template registration.  The registry metadata content will likely be derived from the ISO 15000 eBusiness Registry Information Model which provides a schema for registry metadata.  There are open source implementations of these specifications available on Source Forge, and the registry standard is freely available  on the OASIS web site.  It will include by necessity some limited ability to integrate through terminology services likely through a very simple interface, and will also house a light-weight template repository for those contributors who cannot store their artifacts elsewhere on the web.  The first UIs will be very light on features.

Iteration II will add UI to support terminology lookup and review processes.

During the meeting we identified a new requirement not previously captured which was the ability to mark templates that an organization is using.  This could be used to make the community aware of who is using a particular template for the purposes of notification (which we did cover in the requirements), but which could also be used to help build a community around templates.

In parallel with these efforts we will need to review available technology for the notification infrastructure, user credentialling and audit, and possible infrastructures to incorporate that support CTS.

All in all it was a successful kick-off, and at least 15 people signed up to help in different phases.

     Keith