Monthly Archives: October 2013

Straw Poll: FHIR Document Resource Name

FHIR defines a resource called Document. It describes a way to assemble a set of resources to act as a “Clinical Document” – an set of resources that have an attested content, and carry their own context. Kind of like CDA – in fact, a lot like CDA.

Technically, the Document resource is actually a bunch of pointers to other resources, and some glue attributes around attestation and presentation. The resources correspond to the CDA header (patient, author, attester, encounter, etc) and the body ( a tree of sections , each with a code and a resource that provides the content). You can see an example here: http://hl7connect.healthintersections.com.au/svc/fhir/document/@1/history/@1.

When you’re dealing in a pure RESTful environment, you can treat the clinical document as a bunch of disparate resources, each accessed separately. Kind of a virtual document, in a way. But while that’s pretty convenient for processing data atomically across documents, it presents a set of challenges:

  • How can you be sure these things don’t change?
  • How can you reassemble exactly what was attested?
  • How can you move the whole document in one go?
  • How can you ensure that the whole document is available?

These issues are especially obvious if you’re used to the CDA paradigm, and not to REST. But they’re all valid issues. So to make document handling possible, FHIR defines a way to stitch all those disparate resources into a single “bundle” (which is an atom feed in XML) with a tag (feed.category) of “http://hl7.org/fhir/tag/document” that marks it as a “Clinical Document”. You can see the same document as the previous example in a fully assembled document here: http://hl7.org/implement/standards/fhir/document-examples.html

There’s a duality here – a Document resource, that describes a logical clinical document, that can be assembled into a “Document” – that is, a Document Bundle that is an actual clinical document.

The Naming Problem

As that previous sentence makes clear, we’ve got a naming problem – naming the resource “Document” creates potential for confusion between the Document Resource and a Document Bundle. I kind of hoped that it wouldn’t be a problem, that we’d use “Document Bundle” for the whole thing – but I haven’t even done that in the specification. So we’ve decided to rename the resource to something else to reduce the confusion.

The trouble is, what? So the project team and the implementers skype channel have been casting around for a name, and we’ve considered a lot of candidates. But we don’t really like any of them enough to get consensus. So this is a straw poll: which of these do you like, and why?

  • “DocumentHeader” – It’s the thing that stands at the head of the document. But in CDA terms, it’s not just the header, it’s the sections as well. So potentially misleading for CDA people.
  • “DocumentOutline’ – it’s the outline of the sections, and the outline of the header information (all references) – but we think most people would think it didn’t include the header part
  • “DocumentSpine” – same comments as document outline
  • “DocumentBackbone”  – same comments as document outline
  • “DocumentBase” – it’s the base of the document – whatever “base” means. Very obscure
  • “DocumentRoot” – same comments as DocumentBase
  • “DocumentGlue” – well, it holds it all together, but it’s more than that
  • AttestedCollection – because that’s part of what it is – this was an attempt to get away from document altogether – but it’s narrower than an attested collection – it’s specifically got document aspects
  • DocumentStub – this might be my favourite at this point, because it sounds painful
  • DocumentMeta
  • DocumentShape

Someone suggested “DocumentWithLeavesOutsideInAFeedSomewhere_MaybeHereMaybeNotBut DefinitelyAccessibleUnlessItsDownSoYa” – but perhaps we can do better than that?

So, vote in the comments please (or the FHIR mailing list, or email me privately if you aren’t allowed to do either of those) – thanks

Clinical Safety Workshop for Healthcare Application Designers

On November 12 in Sydney, I’ll be leading a “Clinical Safety for Healthcare Application Designers” workshop on behalf of the Clinical Safety committee of the Australian Medical Software Association (MSIA). This is the blurb that went out to MSIA members today:

Ensuring the clinical safety of any healthcare application is vital – but it’s hard. Not only do the economics of the industry work against it, most of the information available is targeted at the clinical users, and often isn’t relevant or useful to application designers. But it’s the designers who make the important choices – often in a context where they aren’t aware of all the consequences of their actions, and where feedback, if it comes at all, is unreliable and often unusable.

Attendees at the MSIA clinical safety workshop will work through practical examples (often real) to help raise awareness of clinical safety issues in application design, and provide attendees with a set of tools and plans to mitigate the issues. Topics covered include general clinical safety thinking, and identification, classification, presentation, and data access, migration and aggregation issues.

The workshop is sponsored by the MSIA Clinical Safety Committee, and will be lead by Grahame Grieve, who has 20 years of experience in healthcare, application design, information exchange, and also served on the PCEHR clinical safety work group.

Not all MSIA members are on the distribution list, and some of the target audience track my blog, so I thought I’d announce it here. Attendence is restricted to MSIA members, and it’s free. If you’re not on the Bridget’s (MSIA CEO) email list, and you’re interested in attending, send me an email.

 

What impact will FHIR have on the Healthcare Integration Market?

Yesterday, I gave a FHIR update as a keynote presentation at the International HL7 Interoperability conference (IHIC) on the subject. You can get my slides from the IHIC website or the FHIR SVN. As part of that presentation, I discussed the likely impact of FHIR on the Healthcare Integration Market.

FHIR will Drive Interoperability Costs Down

FHIR is going to reduce the cost of interoperability. Here’s why:

  • FHIR is designed for implementers
  1. It’s written to be understood and implemented
  2. The resources are described in the language of the problem
  3. There is Quality and Consistency, but in the background
  4. Version Stability is inherent in it’s design – it has to be, because it’s a repository specification (like DICOM)
  5. FHIR comes with 1000s of examples
  6. There’s broad and deep (and growing) Implementation assistance: code, Live Servers, Regular Connectathons
  • FHIR Re-uses Technology and Patterns
  1. We copy Facebook, Google, Twitter, Stack Overflow, etc wherever we can
  2. The skills and libraries for this are widely available
  3. The RESTful API can be used in all sorts of creative ways
  • FHIR is Free and Accessible
  1. There’s no limitations on use of distribution. This is particular good for open source.
  2. It’s published as web site – send direct links to the current site, no problems with currency of versions
  3. All documentation, tutorials, etc, are published under open licenses

The combination of all this is going to drive the cost of providing interoperability down (see John Halamka’s take on this). It’ll be easier to develop, troubleshoot, maintain, and leverage in production environments and there’ll be more and cheaper people to do the technical work.

And the best part is that competing approaches – the ones that already exist – they’re going to have to compete: their cost has to go down as well. This effect is already being felt in other HL7 standards (IP changes, extensive examples, more focus on implementers). It’s all good.

Except maybe for people like me.

Market Spend will go up

But actually, I think that the amount of money that is spent on Healthcare Integration is going to go up dramatically. The reason is simple, and can be described really simply, using a derivation of the Velominati rule #12:

The correct amount of integration is n * 2, where n is the amount you currently have

I’ve seen this again and again – the more integration you get, the more you need. And since FHIR is going to make it easier to get integration to pay off, people are going to want more – lot’s more.

The total amount spent on Healthcare Integration will rise dramatically. But the work will change – the technical challenges will recede into the background, and while that will lift people’s expectations of what they can get, policy and informatics questions are just going to get harder as integration scales up. So, maybe people like me don’t need to worry so much after all.

Where will FHIR be used?

Since the start of  the FHIR project, I’ve been predicting that FHIR will initially be used in new areas where there is not a lot of existing implementation, In particular:

  • Personal Health data + access to institution health records + Social/Mobile/Big Data. I call this “connected health”
  • Device Data management (particularly as an adjunct to connected health)

A quick scan of the PHR Market – 100s of providers, 1000’s of health data providers (at least), and about $100,000 per connection between PHR and data provider (that’s what my market scan tells me is the overall total cost including contracting, management, development, testing, support…) should tell anyone that this isn’t going to work. The PHR/Data provider connection needs to be commoditized. And that’s the first place that FHIR’s going to have an effect.

But another area’s been sneaking up in the implementation work that we’ve done to date:

  • Existing Healthcare Regional and National Repositories

These already exist, and so we (the initial project team) didn’t really expect that FHIR would start to be used in these quickly. But I’m hearing that these projects are really feeling the overall cost factor – they need more bang per buck. But the work with IHE to include FHIR as part of the XDS suite (through the MHD project) and the possibility of using FHIR piecemeal as adjuncts to existing repositories has lead to much more interest in this space than I expected to see at this stage of the process.

But there’s one last area, a real frequently asked question: will FHIR replace version 2 messaging? From the beginning, we’ve designed FHIR so that it has the capability, but we really didn’t expect that this would happen anytime soon – v2 is pretty well understood and why would you change what works? We expected this to happen only very slowly, and mainly driven by external use impacting on existing internal processes. But after the IHIC meeting, I’m not so sure.

Jamie Ferguson (CIO at Kaiser Permanente) gave a great presentation about new policy directions in the security/privacy space. I’ve known that this has to happen, particular in the post-Snowden era, but I’d never stopped to consider the full ramifications of this. Jamie’s presentation goes through the full ramifications of the changes afoot in society and technology now – I highly recommend his slides, which you can get on this IHIC website. Where this is of interest to FHIR is that the logical consequence of Jamie’s policy directions is that every existing interface is going to have to be revisited and re-implemented to support all this. And further, we’d have to retool HL7 v2 to support all this, while FHIR already does – I think (We need to do more work around this – I think we have the touch points, but we definitely need more work yet. We’ll have to make this a focus of a future connectathon).

So now I’m beginning to wonder – we might see FHIR replacing HL7 v2 rather sooner than we expected.

More fun with original Text

As I’ve described before (and here) originalText is a challenge.

Firstly, originalText is a consistent pattern throughout the HL7 data types (v2, v3, and FHIR) is that a coded value is represented by some variation of a cluster that contains

  • (code / system / display) 0..*
  • original text

There’s variations to this theme amongst the CE/CNE,/CWE, CD/CE/CV, and Coding/CodeableConcept, but they all have the same basic pattern. The multiple codes are for equivalent codes that say the same thing in different coding systems. Here’s a v3 example (from the spec):

<code code='195967001' codeSystem='2.16.840.1.113883.19.6.96' 
    codeSystemName='SNOMED CT' displayName='Asthma'>
  <originalText>Mild Asthma</originalText>
  <translation code='49390' codeSystem='2.16.840.1.113883.19.6.2' 
   codeSystemName='ICD9CM' displayName='ASTHMA W/O STATUS ASTHMATICUS'/>
</code>

This has the original text “Mild Asthma”, and two different codes, one from ICD-9-CM, and one from Snomed-CT. That’s a pretty straight forward idea.

The problem

But what if the original text is something a little more complex?

Diabetes & Hypertension

The problem with this original text is that there’s going to be two codes. If we stick to just Snomed-CT, this is codes 73211009: Diabetes mellitus, and 38341003: Hypertensive disorder, systemic arterial (I think). There’s no appropriate code that covers both. And this:

<code code='73211009' codeSystem='2.16.840.1.113883.19.6.96' 
    codeSystemName='SNOMED CT' displayName='Diabetes mellitus'>
  <originalText>Diabetes & Hypertension</originalText>
 <translation code='38341003' codeSystem='2.16.840.1.113883.19.6.96' 
   codeSystemName='SNOMED CT' displayName='Hypertensive disorder'/>
</code>

is not legal, because there’s no way that these two codes fit anywhere near the definition of

The translations are quasi-synonyms of one real-world concept. Every translation in the set is supposed to express the same meaning “in other words.”

And this becomes not merely a thereortical problem if you’re trying to provide translations to yet another code system as well. So this is a problem – you have to pick one of the codes.

I suppose you could tell the user that “Diabetes & Hypertension” is not a valid text to insert. I’m sure they’ll be fine with that.

Not

2nd try

An alternative is to say that we ensure that in the circumstance this can arise – say, the reason for prescribing a medication – allows 0..* coded data types, not just 0..1. Then we can do this:

<code code='73211009' codeSystem='2.16.840.1.113883.19.6.96' 
    codeSystemName='SNOMED CT' displayName='Diabetes mellitus'/>
<code code='38341003' codeSystem='2.16.840.1.113883.19.6.96' 
   codeSystemName='SNOMED CT' displayName='Hypertensive disorder'/>

Only, where did the original text go? Well, you could repeat it, I suppose. That’d be technically correct:

<code code='73211009' codeSystem='2.16.840.1.113883.19.6.96' 
    codeSystemName='SNOMED CT' displayName='Diabetes mellitus'>
  <originalText>Diabetes & Hypertension</originalText>
</code>
<code code='38341003' codeSystem='2.16.840.1.113883.19.6.96' 
 codeSystemName='SNOMED CT' displayName='Hypertensive disorder'>
  <originalText>Diabetes & Hypertension</originalText>
</code>

So now, a receiving application has to rip through the codes and eliminate duplicate original texts – that’s not my favourite outcome.

FHIR

We have a third option in FHIR: break apart the data type, and declare that the containing element (the reason for prescription in this case) isn’t a CodeableConcept, but a complex element that has a have a text element, and 0..* coding elements that don’t have to be equivalent:

<reasonForPrescription>
 <coding>
   <code value='73211009'/>
   <system value=http://snomed.info/id"/>
   <display value='Diabetes mellitus'/>
 </coding>
 <coding>
   <code value='38341003'/>
   <system value=http://snomed.info/id"/>
   <display value='Hypertensive disorder'/>
 </coding>
 <text value="Diabetes & Hypertension"/>
</reasonForPrescription>

Actually, this has exactly the same look on the wire, but it’s defined differently. So this is ok, but there’s no facility for providing translations to other code systems (and the RIM mapping has now become impossible because we haven’t solved this for the RIM)

Conclusion

Original Text continues to be a problem because it cross-cuts the coding structures. If only we could force end-users to value coding enough that we could get rid of text 😉

 


			

Unique Device Identifiers in FHIR

The FDA and partners around the world are in the process of introducing a new identification framework for medical devices called the “Unique Device Identifier” (UDI). They asked for FHIR to “support” UDI. But what does that mean?

First, some background on what a UDI is, and then some analysis of the use cases for UDI in the scope of FHIR.

What a UDI is

A UDI is a barcode (or series of barcodes, or even an RFID) on a medical device that carries the following information:

  • Device Identifier (Mandatory)
  • Lot Number
  • Serial Number
  • Manufacture date
  • Expiry Date

The first element is the key piece of data – it represents the key that can be used to look up information about the device in the public device registry (GUDID or equivalent). It is referred to as the DI (Device Identifier). There’s also the other fields, which are called the PI (Production Information).

The UDI may identify a specific instance of a device (e.g. no other device will have the same UDI), or it might not – it’s up to the manufacturer to decide whether to put a serial number in the PI. This example from the FDA web site shows a prototypical (and fictional) device label:

UDI example

The UDI is represented a the bottom right, in two forms, the barcode and the human readable information below it. Here’s a different example, just the barcode (a GS1 example):

gs1-barcode

 

This UDI is understood as:

(01) GTIN DI (A DI defined by GS1) 00614141999996
(17) Expiry date 1-Jan 2010 (YYMMDD)
(10) Batch number 123ABC
(21) Serial number 1234567890

There’s some subtleties around this barcode, I’ll discuss this more below.

Use cases for the UDI

The UDI comes out of the supply chain, and it seems that the use of the UDI is well understood there. But it’s less well understood what the goals of support UDI in the space that FHIR occupies (patient management / clinical workflow / clinical record, mainly). It’s been hard to get a good set of requirements. This is what I’ve got so far:

  • The primary use cases are to allow the device to be looked up in the registry, and to foster analysis of the impact of product recalls
  • It would be nice to use the UDI to track an instance of a device, but it’s not reliable for this generally, because it doesn’t need to have a serial number
  • In particular, tracking the UDI for patient implants, so that a clinician can see information about the patient’s implants, manage recall issues, and track adverse events

But still, much is unknown. For instance:

  • When do systems need to consult the registry?
  • Which systems need to understand the internal structure of the UDI? (Is it all of them?)
  • If you have the UDI which contains production information, do you need to exchange the production information separately? Or do you assume that the other systems can extract the PI from the UDI? what if there is production information available that’s not in the UDI? What if they source differs?

So many questions. But at least I got an answer on one question. I wanted to know whether there was a need to exchange the raw UDI, or whether you could just break it up into it’s parts and send the parts in separate slots in the message. I identified 3 reasons why you’d need to send the raw UDI:

  1. Because you need to reproduce the original UDI for display to a human user (so they can verify the device information matches themselves). Since the order of the parts is optional, you need to original to show it correctly to the user
  2. Because some systems don’t know how to process the UDI at all, but gather it from the device (is that realistic? allowed?)
  3. Because the slots for exchanging the PI don’t exist anyway, and all you can do is the full UDI as a single identifier

The answer to that is that FDA strongly endorses the first use case, and believes that this is necessary.

GS1 Barcode Issues

So it turns it there’s a trick to that with GS1 barcodes (This section is specifically about GS1 barcodes – I haven’t investigated the others). Consider this example from above:

gs1-barcode

 

This is actually a dual representation. Most obviously, there’s the human readable information, which is (01)0061414999996(17)199191(10)123ABC(21)1234567890. But when a bar code scanner scans the bar code, what it might get depends on it’s configuration. The full representation of the barcode is ]C101006141419999961710010110123ABC<GS>211234567890. ]C1 is the ISO/IEC symbology identifier indicating GS1 formatted data in a code 128 (I’m not clear whether code 128 is the only way UDIs are represented btw). <GS> is a non-visible ASCII character (29) which is a separation marker that marks the end of the variable length batch number. Without that separation marker, that number is not parseable. For example, when I scanned this barcode with a standard USB bar code scanner that drops the scanned barcode into the keyboard buffer, what I got in my application was “01006141419999961710010110123ABC211234567890” – which is not parsable. What exactly the barcode scanner returns depends on how it is configured, and also it appears that the separator character doesn’t make it through the keyboard buffer. The take away message is that scanning and parsing the UDI may require special bar code scanning support which is different to existing arrangements in clinical practice.

Exchanging the UDI

So the question is, which representation should be used to exchange the UDI in practice? Well, if the goal is to be able to show to the user – and it is – you need to exchange the Human Readable Information (HRI) – that is, the form (01)0061414999996(17)199191(10)123ABC(21)1234567890. Conveniently, this is easily parseable. I’m yet to check the bar codes from the other definers of UDI.

There’s another HL7 concern here – HL7 is careful to distinguish between type and instance identifiers. Because this makes a big difference to how you use these numbers, and rely on them. So HL7 typically calls the first (type identifier) a “code” and the second (“instance identifier”) is typically called “id”. UDI is one or the other, depending on it’s specific contents in the PI… that’s tricky.

So, at least in the context of FHIR, supporting UDI becomes clear. Anywhere a device is involved in the care process, the resource that describes the process should reference a device resource – which describes the resource. The device the resource has the following simple structure:

device

This has a specific field for the whole UDI, and other fields for the parts of the UDI  – the DI goes in the type as a code, and the PI goes in the appropriately named fields. These can be filled out from the UDI or from other sources. Concerning the UDI, the spec says (or will, when it is next updated):

  • The UDI has it’s own element, which  carries the human readable representation of the UDI shown in the bar
  • The UDI may identify an instance of a device uniquely, or it may just identify the type of the device.
  • A portion of the UDI – the DI part – can be extracted from the UDI and/or carried in the type element. When required, it can be used  to look up information about the device through the GUDID.
  • Where the device has an assigned UDI, the other details carried in the resource (lot, expiry date etc) SHALL be consistent with the information encoded in the UDI or reigstered in the GUDID.

I’ve written this into the draft, which will make it’s way to the website soon, and then it will under go the normal ballot review process (all this is driven by a FDA ballot comment on FHIR that UDI needs to be supported)

JSON, property order, polymorphism, and streaming based parsers

On the FHIR email list, we’ve been discussing a proposal to simplify the FHIR JSON representation.

The core problem is that in order to deal with a point in the structure where there’s a choice of types, we did it like this:

{  property-name : { 
  choice-name : { 
   choice-properties }  
  } 
}

There’s a list of what choice-name can be for each point where we have this structure. And the different choices share common properties – this is a case of polymorphism. This is a format that doesn’t suit consumers who navigate the the JSON directly, though. In order to navigate to the common choice properties of the thing that is represented by choice-name, you have to skip the choice-name. So it would be something like this in javascript:

property-name[Object.keys(property-name)[0]).choice-property-name]

Yuck. So after discussion about this at the HL7 face to face meeting, we changed the representation to this:

{  property-name : { 
   type : choice,  
   choice-properties  
  } 
}

This form of representation has two problems:

  • As far as I can read JSON schema, JSON schema works like XML schema – content models are tied to property names, and there’s no way to make it so that the content model depends on the value of a property. We decided we didn’t care. No one has mentioned JSON schema to us as an implementation good (though someone has now)  (later update: this may not be true now. JSON schema investigation is on the to do list)
  • You can’t use a streaming JSON parser (and there’s lots of these) with the second approach, because the type property may not come first, and so you’re reading the thing before you know what type it is. Well, you can, but the scheme roughly works like this: cache the stream, saving the events until you come to the type property. Then reparse the stream again, and then go on. And… this can happen in a nested fashion. YUCK.

So we kind of have a choice:

  1. A JSON syntax that works well for clients, but is a bitch to parse efficiently for a server
  2. A JSON syntax that isn’t hard for streaming based parsers, but isn’t so nice for client type processing
  3. Fix the property order so that the type property comes first.

Note, btw, that this isn’t a problem for parsers based on an object model – the majority of parsers – because then you can access the data in an object structure, and order simply doesn’t matter. JSON defines properties as an unordered map of name / values, and therefore it doesn’t really cater to streaming based parsers (and option #3 above would be problematic in the extreme, since many libraries can’t control the order of the properties)

It seems to me that this problem is not specific to FHIR – it’s going to arise anywhere you mix polymorphism, JSON, and streaming parsers. But googling around, I can’t find any information about this. Take, for example, this JSON example:

{
  "animals":
   [
     {"type":"dog","name":"Spike"},
     {"type":"cat","name":"Fluffy"}
   ]
}

This is from a code snippet where the author is writing about deserializsation into Java classes – exactly the problem I’m talking about here: what do you do if type doesn’t come first? That’s never discussed, and I can’t be bothered reading the Jackson implementation in detail to figure out what the right questions to ask are. But note this, from the Jackson advantage list:

incremental (“streaming”) parsing and generation: high-performance, low-overhead sequential access. This is the lowest-level processing method, comparable to SAX and Stax APIs for XML processing. All packages must have such a parser internally, but not all expose it.

The alternate approach is here: http://stackoverflow.com/questions/5186973/json-serialization-of-array-with-polymorphic-objects – this is not so good for client based processors of the data, but nice for SAX based parsers.

It seems that JSON isn’t that simple after all.

Update: Json.NET, the most popular json parser for .NET *is* dependent on order: http://stackoverflow.com/questions/17032769/json-net-seems-to-rely-on-type-being-the-first-property-is-there-a-way-to-lift

On the subject of original text for Codes

In the various coded data types defined by HL7 across v2, v3, and FHIR, there’s a property named text or originalText that is defined using some variant of these words:

The text as seen and/or selected by the user who entered the data which represents the intended meaning of the user.

Original text can be used in a structured user interface to capture what the user saw as a representation of the code or expression on the data input screen, or in a situation where the user dictates or directly enters text, it is the text entered or uttered by the user.

Unfortunately, what this exactly means is a matter of interpretation. The key question is, to what degree does the context affect the interpretation of the text that represents the code, and therefore, to what degree does the context contribute to the original text?

I’ll illustrate the discussion with an example. In SNOMED CT, there’s a (large) heirarchy for organism type. Part of the hierarchy contains codes for virii. A subset of this is found in the PHINVADS value set “Virus types answer list specific to Arbovirus/ArboNet reporting“. This lists 17 codes for type of virus. So you could easily imagine some kind of UI, for instance, where users would select one of the codes from a pick list:

In this case, the original text is the same as the Snomed-CT preferred name, and it’s pretty straight-forward to understand. If, for instance, the user picked “Eastern equine encephalitis virus”, then that’s the original text, and nothing further is needed.

However, a lot of system designers will look at this and say, the word “virus” is repeated in every entry, and that’s just a tax on the users. We should get rid of it. That would give you an entry like this:

Actually, in this case, the example is pretty trivial. “Virus” isn’t hard to read. But how about this SNOMED CT preferred term: “Cholecystectomy with exploration of common bile duct and choledochoenterostomy” – there’s quite a lot of potential for useful simplification there, especially where the set of codes are all siblings, such as the variations of strength in a particular medication:

This somewhat extreme example is from AMT. I doubt any reader can even figure out the differences between those 4 codes. How much easier this is:

Hopefully that example will serve to illustrate that this isn’t just a UI best practices issue – as the codes become finer, it starts to become a clinical safety issue too.

Back to the virus case: if the user picks “Eastern equine encephalitis”, then is the original text “Virus: Eastern equine encephalitis” or just “Eastern equine encephalitis”? What actually works best depends on quite how the original text is going to be used. If the original text is used as the faithful reproduction of the meaning of the user in a similar context as the user entered, then the minimal text the user actually picked is the useful original text – but how similar? If, on the other hand, the original text is used out of context, the full context of the data entry of the code should be represented – but this could be a combination of the text the user actually picked, the field name, additional words taken out of the explicit context on the screen, and even some text that is implicit in the clinical context.

To make things even more fun, a contributor on the HL7 vocabulary mailing list offered this example:

aafbgbbi

 

I’m not sure what the best way to resolve this. How do you make original text reliably useful for both uses when the user interface isn’t nailed down?

Well, one way is to rely on the value set – the value set description should contain the information that is implicit in the context. So the true original text would be the value set description + the user picked text. Though I don’t think that any particular field in the value set (either v3 or FHIR) is defined for this purpose in mind. Perhaps that’s something we should address?

 

Updated note about MIMS codes in CDA documents

When representing MIMS codes (from their Integrated Data Solutions Product) in CDA documents, you use the OID 1.2.36.1.2001.1005.11.1:

<code code="83510101" codeSystem="1.2.36.1.2001.1005.11.1"
  codeSystemName="MIMS Standard Code set" codeSystemVersion="20110900" 
  displayName="Ganfort 0.3/5 Eye drops 3 mL [1] (Restricted - PBS/RPBS) rpt: 5"> 
 <originalText><!--insert originalText here--></originalText> 
 <translation code="78835011000036104" codeSystem="1.2.36.1.2001.1004.100" 
   codeSystemName="Australian Medicines Terminology (AMT)" codeSystemVersion="2.25" 
  displayName="GANFORT 0.03% / 0.5% eye drops: solution, 3 mL"/> 
</code>

For documentation of this:

What’s not clear is quite what goes in the code. After discussion with MIMS, the only acceptable code to be used in association with the OID 1.2.36.1.2001.1005.11.1 is a full triple comprised of Product : Form : Pack. This would be a number with at least 5 digits,  such as the 8 digit one shown above. The last 4 digits are the form and the pack codes (2 digits each).

This is just a heads up to anyone working with MIMS codes in CDA documents. The OID registration should be updated shortly to be specific about this too.

Update: the OID registry has been updated

 

Why healthcare interoperability standards aren’t perfect

Referring to HL7 and other SDO’s, Tim Cook writes:

Such consensus groups gather political power from their expertise on healthcare IT standards, but they are seldom aware of all the problems real software companies dealing with real customers are facing. After many months or years, and hundreds or millions of dollars or euros spent, this little group of experts define a data model, a message or a schema, and they want to enforce it on everybody. Your customer gets frustrated, because that seldom matches the way clinical practictioners want their data collected, because the conventional top-down standards are much more concerned about the information needs of central governments or large medical hardware corporations than with the routine clinical documentation, which is the essence of medical decision making that really impacts on patient outcomes.

This is both true and false. I can’t decide which it’s more of. I’ll confine my comments to HL7, which is where I can speak with some knowledge.

Who goes to HL7? A mix of people. You can check Dave Shaver’s run-down, or just use my simplified list:

  • Health software developers
  • Academics
  • Government policy representatives
  • Integration contractors/consultants

HL7 was traditionally vendor driven: a focus on “problems real software companies face”. That slipped, when the people trying to solve the problems got too ambitious – but it’s coming back. FHIR is both an outcome and an input to this – it reflects the fact that HL7 is focusing more on practical problems, and it drives a more practical approach. There is a need to reflect policy, but policy input can only be limited by the fact that policies differ so wildly.

With regard to the fact that this seldom matches the way practitioners want their data collected, my belief is that the fundamental underlying problem is that there’s so little agreement amongst the practitioners about how they want their data collected. This makes the standards process easily fall hostage to some particular small clique of practitioners who think it should be done in one particular way. I call this clinical activism, and I’ve seen it again and again. The government processes are particularly prone to this – they have to work with clinicians who are prepared to work with them, and there’s an inherent self-selection process at work there.

However it is true that the outcomes of the standards will reflect the prejudices of those who bank-roll it. And for bigger enterprises, it’s a smaller fraction of their budget. So they can afford it more easily. And the standards do unduly reflect their goals. But hang on, aren’t their goals to sell more software, to make things better? In as much as the standards don’t solve the problems that Tim wants solved, the standards don’t meet the goals of the “needs of central governments or large medical hardware corporations”.

So, how to fix this? I’d like to see

  • More clinical record keeping standards (not IT ones)
  • More engagement with the standards process by professional associations reflecting people who actually work at the coalface, and can’t easily afford to participate

But, of course, engagement with standards takes years to bear fruit, and actually involves compromise. It’s really hard to find people who are willing to engage for years only to not get what they want.

As a general comment on the the roll-your-own scheme in the reference above: it sounds like Tim is just rerunning the whole RIM design approach again to me. I can’t really tell the difference between his goals and methodology, and that of the RIM or even openEHR. There’ll be some differences, from not falling into some of the RIM pitfalls (i.e. USAM), but openEHR already avoided those. What I’ve learnt, though, is that interoperable meaning is *hard* – you won’t get it without one of two things: expensive data conversion points everywhere, or community driven consensus.

Community driven consensus is the expensive bit, and always will be.

Question: v3 development resources

Question

I am attempting to develop an implementation of the hl7v3 standard in PHP (specifically the CDA messaging portion) for MU2 certification.  I have been searching various sites and have downloaded the RIM specs (rim0241c.zip).  My problem is the mif seems to be somewhat proprietary, and the UML versions won’t open in any UML tool that I have tried (all error out).  Where can I get a decent view of the models / model structure so that I can create a useful and meaningful implementation (so far the RIM.png is all I can find)?

Answer:

You need the full v3 specification, which includes a number of processible resources – at least, that is, what’s possible to provide given the way v3 works.

You can get it here: http://www.hl7.org/implement/standards/product_brief.cfm?product_id=306

Seriously, the MIF is your best option. Sure, it’s proprietary (more than somewhat) – but that’s what there is. And there is a MIF for CDA. See more about the MIF here: http://vimeo.com/1742299

But why do all this? for CDA? It’s just overkill – all stuff you ain’t ever going to need. Just do CDA – it’s about 2 orders less complex than all of v3. Like building a bulldozer so you can plant a single flower….  Use the schema, and go from there.