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

Friday, September 16, 2016

Other People's Stuff

Everyone likes to use their own toothbrush.  We know where it has been, and it fits our hand perfectly.  Someone else's toothbrush is just, well, ick!

The problem with standards is that they often have that "other person's toothbrush" feel to them.  It's not the way I'd do it, or I don't understand why they did X when clearly Y is so much better.  It takes a while sometimes to overcome that icky sensation of putting that thing in our mouth.

Eventually, if we keep at it, it becomes ours, to the point that we might actually find ourself facing the very same challenge trying to convince others to use what has now become "our standard."

It is certainly a true statement that trying to learn something new, or use something different that we are accustomed to is hard.  "I don't have time for this, why can't I just do what I've been doing?" I hear.  In fact, you might actually not have time.  But you may also be missing an opportunity to learn from what others have done.  Only you can decide which is more important.

Standards is all about using other people's stuff.  Few people are in a position to craft standards, many more are in a position to use them.  If, though, after asking yourself the question of "Is this the stuff I need to be worrying about, or is something else more important?"  you come to the conclusion that there is something more important to be worrying about, consider whether using other people's stuff might benefit you, so that you can move on to that more important thing.

It's always easier to understand what you did on your own, rather than to comprehend someone else's work and logic.  But that logic and rationale is present.  If you learn the knack of it, you can do awesome things.


Wednesday, September 7, 2016


Ch-ch-ch-ch-Changes (Turn and face the strange)Turn and face the strainCh-ch-ChangesDon't have to be a richer manCh-ch-ch-ch-ChangesCh-ch-Changes (Turn and face the strange)Don't want to be a better manTime may change meBut I can't trace time -- David Bowie

I'm more than six months into my new position, and there have been a lot of changes over the past few months.

I dropped my eldest daughter off at college last week.  I still haven't adjusted to that.  I found myself wondering at 4:00 today why she wasn't home from school yet.  Oh yeah, I reminded myself.  November for Thanksgiving.

Next week I finish my last class in my Masters in Bioinformatics.  That and turning in my final capstone paper are all that stands between me an my degree.  I've learned a lot over the last three years in that program, and I cannot recommend it highly enough.  Bill Hersh has put together a great program at OHSU.  Whether you go for the certificate, the masters, or even just the 10x10 program, it's all good stuff.

My standards work is slacking off as my implementation work is picking up.  I'm principle architect for three teams working on Interoperability stuff.  I wear three hats. Some days I'm an architect, others a product manager, and others, an engineering manager.  Some days I do all three, sometimes at the same time.

My schedule is split between three time zones, the usual left-coast right-coast for the US that has been the norm for most of my life, but now also about 4 hours in the middle of the night (12am -4am) Bengaluru time.  I sleep when I'm tired, which is not as you would expect to be "most of the time".

I still struggle with what I want to be when I grow up, forgetting that since I managed to reach 50 without doing so a couple of years back, I don't actually have to grow up, and I have a certificate from my family to prove it.

I suppose that some day when I retire, I will want to teach full time, rather than spending about a third to half of my time doing that.  What I think that really means is that my projects will become my students, rather than having students because of my projects.

Now if I could just figure out how to get the next six things done that I need to before the day is over, without moving to somewhere like Mars, or worse yet, Mercury or Venus.


Tuesday, September 6, 2016

FHIR in India

In case you missed me, I've just gotten back from a fifteen-day long trip, where I spent the last eleven days of it in India.  While there I conducted three training sessions on FHIR, one internally at GE offices in Whitefield, Bangalore, one for HL7 India, and a final one for a partner organization in Mumbai.  While in India I gave an overview of FHIR to nearly 200 software developers working in Healthcare.

Image via @msharmas

There's a great desire to learn more about FHIR in India, and I was privileged to be there to spark the fires as it were.  I am grateful to HL7 India who was able to pull together a half-day plus session in Bangalore on short notice.  I expect we'll be doing more together to follow up, as I expect I'll be back later to conduct some advanced sessions.  I'm also trying to get a FHIR Connectathon started in India as well, more on that later as plans come together.


Sunday, August 14, 2016

Well, Shit.

My twitter feed is all abuzz this morning on the death of @jess_jacobs. Jess is a woman with a challenging illness who documented some of the complete failures of our health system to provide her with even barely adequate care  I've met her briefly about four times in my life. Her death saddens me this morning, not because I knew her well, but because she did great things with her life, and because we share at least one thing in common, our jackets. But in some ways I feel the way that others do when their favorite celebrity dies.

Among many of my friends Jess IS a celebrity.  But outside our world, she is not known well enough, nor is her story told often enough.  So I will walk today in honor of Jess, and instead of telling my story, I will tell hers.


Friday, August 5, 2016

Offering an Informal FHIR Chat, Whitfield area, Bengaluru, India

I'll be in Bangalore for about 10 days later this month, to work with several of my teams during the week of the 22nd, and to deliver some standards training internally the following week.  One of my architects suggested that we set up an informal FHIR chat on the weekend I'll be staying through, either Saturday, August 27th, or Sunday August 28th for folks in India who want to learn more about FHIR.

Timing is too tight for me to arrange a venue through any sort of official channels, however, others in the region might be able to put something together.

So, here is the offer.  I'm free for the entire day either Saturday or Sunday, and can deliver an overview of HL7 FHIR for developers in India.  If you are interested in helping to pull this together, please either leave a comment for me here, or e-mail me at


Friday, July 29, 2016

Round tripping identifiers from CDA to FHIR and back

I think I solved this problem for myself last year or so, or else the answer wouldn't be so readily available in my brain.

The challenge is this: You have an identifier in a CDA document.  You need to convert it to FHIR. And then you need to get it back into CDA appropriately.

There are four separate cases to consider if we ignore degenerate identifiers where nullFlavor is non-null.
  1. <id root='OID'/>
  2. <id root='UUID'/>
  3. <id root='OIDorUUID' extension='value'/>
For case 1 and 2, the FHIR identifier will have system =  urn:ietf:rfc:3986, and the value will be urn:oid:OID, or urn:uuid:UUID.
For case 3, it gets a tiny bit messy.  You need a lookup table to map a small set of OIDs to FHIR URLs for FHIR defined identifier systems.  If the OID you have matches one of the FHIR OIDs in that registry, use the specified URL.  Otherwise, convert the OID to its urn:oid form.  If it is a UUID, you simply convert it to its urn:uuid form.

Going backwards:
If system is urn:ietf:rfc:3986, then it must have been in root-only format, and the value is the OID or UUID in urn: format.  Simply convert back to the unprefixed OID or UUID value, and stuff that into the root attribute.

Otherwise, if it is a URL that is not in urn:oid or urn:uuid format, then look up the identifier space in the FHIR identifier system registry, and reverse it to an OID, and put that into root.  Otherwise, you just convert back to the unprefixed OID or UUID value, and stuff that into root.  In that case, the extension attribute should contain whatever is in value.

So now then, you might ask, how do I represent a FHIR identifier that is NOT one of these puppies in HL7 CDA format.  In other words, I have a native FHIR identifier, and CDA had nothing to do with generating it.  So, there's a system and a value, but no real way to tell CDA how to deal with it.  To do that, we need a common convention or a defined standard.

So, pick an OID to define the convention, and a syntax to use in value to represent system and value when system cannot be mapped to an OID or UUID based on the above convention.  In this manner you can represent a FHIR identifier in CDA without loss of fidelity because CDA does not provide any limits on value.  Oh, and modify the algorithm above to handle that special OID in case four.

I'll let HL7 define the standard, select the OID, and specify the syntax.  I have better things to do with $100 than register an OID for this purpose.  But clearly, it could be done.


Tuesday, July 26, 2016

Don't ask them to tell me what I should already know

This particular issue shows up quite a bit in standards based exchange, and frankly drives me a bit crazy.  Somewhere in the message someone asks for several correlated pieces of information to be communicated.  A perfect example of this is in the HITSP C32 Medication template.  We had to provide an RxNORM code for the medication, a code for the class of medication, and a code for the dose form within the template.  We also had to provide places to put the medication brand and generic names. Folks insisted that all of this information was useful, and therefore must be communicated in the exchange.

However, we used RxNORM codes to describe the medication.  Have you ever looked at the content in the RxNORM Vocabulary?  If I gave you the RxCUI (code) of 993837 in a communication, here's what RxNORM will tell you about it.

Within the terminology model, I can give you the precise medication ingredients and doses within each tablet, tell you that it is in tablet form intended for oral use, identify the brand name, and generic form.  Now, what where you going to do with all of that other information you asked me to code?

Having redundant information is helpful as it helps you spot errors.  If the code is 993837 and the reported medication is something other than Tylenol #3 or Acetaminophen 300 mg/ Codeine 30mg, then there is a problem.  So, it is helpful to have SOME redundancy.  But when all those other codes are also present, the system needs as much knowledge as is already in RxNORM to produce that information, and we just lost some (if not most) of the benefits of using a vocabulary in exchanging the information.

There's so much redundancy in the coded and fielded information in the HITSP C32 Medication template as to be ridiculous (and while I argued against it, I did not succeed).  The RxNORM code is all you need, and just to be sure that the sender knows what it is talking about, one of either the brand name, or clinical name of the drug. Everything else after than is redundancy UNLESS you can identify a specific use case for it.

In an information exchange, you should pay attention to exchanges that duplicate already existing knowledge about real things in the world, especially when knowledge bases such as RxNorm exist. The need to exchange world knowledge between systems exists when the receiver of the communication cannot be expected to be readily aware of all of that world knowledge.  If I ask you to get rid of the dandelions in my yard, it doesn't really help a whole lot to tell you to get rid of the yellow dandelions, unless I have some very specialized varieties of dandelions or I've been watering them with food die.

If you are expecting someone to transmit information that can be inferred from world knowledge, ask yourself if that is truly necessary.  You should always include enough redundancy to enable a receiver to ensure that the sender knows what it is talking about, but don't include so much that a receiver would be overwhelmed, or the sender would basically be duplicating the content of a knowledge source.  After all, we have reference works and reference vocabularies so that we can look things up.