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.

Wednesday, December 6, 2017

RTF to PDF Conversion

A lot of medical documents are still created in RTF format (or can be readily accessed as RTF).  This is due to the use of Word as a tool in some transcription environments.  Converting these documents to a "standard" format is a bit challenging.

There are some tools that will convert RTF to HTML (or XHTML), but my goal was to be able to convert them to PDF so that I could incorporate the content into the IHE Scanned Document format (and to the HL7 CCDA Unstructured Document format).

I needed this quickly, so I started looking for some open source libraries.  One of the ones I found was LibrePDF.  I had (from a former life) been familiar with the open source iText product, which would have been my first go to, but unfortunately, its licensing model isn't conducive for many to use (it's AGPL, essentially copy-left), even though prior versions had been LGPL or MPL.  It also dropped RTF support in later versions as well.  LibrePDF is a branch from the last MPL version of iText, and still has RTF parsing tools as well.

Unfortunately, LibrePDF doesn't really provide a great deal of information on how to use the components, so here's a quick summary:

To get what you need, including the following two dependencies in your pom.xml:


The first one grabs the LibrePDF core components.  The second grabs the PDF-RTF tools.  When you grab the libraries you will also get bouncy-castle for decryption, encryption and signing.  You can ignore those unless you are going to be creating PDF files that require those capabilities.  For XDS-SD format PDF files, these features are not essential.

Having done that, you can now use this gist from Ajay Ramesh on GitHub to understand how RTF to PDF conversion is done.  You can comment out the line that reads:

   System.setProperty("", "Windows 7");

This is no longer necessary, because the LibrePDF code doesn't have the same problem that iText 4.2.1 had reported on StackOverflow.

Having generated your PDF, you can now wrap it inside a CDA document, or perhaps use a FHIR DocumentReference resource.


Tuesday, December 5, 2017

Cards against Humility

A lot of my friends, including those in the Healthcare Standards space play Cards against Humanity.
If you have a wicked mind, but are fun loving person you've probably played the game.  If you haven't, please note, some of the text on the above link is in the NQSFWD (not quite safe for work depending) range.

This year for Christmas, I'm building some of my friends their very own personal card, in a deck design I call "Cards against Humility". it allows their name to be played in some pretty rude scenarios in the game.  To print the deck, I used, printed rounded cards in the MOO Size using super paper in the high gloss format.

To create the cards I set up a Word template with paper width of 2.32" and 3.46", with margins of .32" inches all around.  The "front" of the card (really the back in this case) is Arial Bold 30pt with the words "Cards Against Humility".  Since the back of each card can be different (really the front), I then simply listed the names of my 50 best friends and family that I wanted to be victims.  I wrote their names in Arial 18pt Bold.

You have to upload the front and each individual back as a separate PDF file to  I did a bit of digging and found a little word Macro to save each page as a separate PDF.  It's listed below.

Sub Word_ExportPDF()
'PURPOSE: Generate A PDF Document From Current Word Document
'NOTES: PDF Will Be Saved To Same Folder As Word Document File

Dim CurrentFolder As String
Dim FileName As String
Dim myPath As String
Dim UniqueName As Boolean

UniqueName = False

'Store Information About Word File
  myPath = ActiveDocument.FullName
  CurrentFolder = ActiveDocument.Path & "\"
  FileName = Mid(myPath, InStrRev(myPath, "\") + 1, _
   InStrRev(myPath, ".") - InStrRev(myPath, "\") - 1)

  For pageNo = 1 To 51 Step 1
    DirFile = CurrentFolder & FileName & ".pdf"
    UniqueName = True
    'Save As PDF Document
    On Error GoTo ProblemSaving
        ActiveDocument.ExportAsFixedFormat _
        OutputFileName:=CurrentFolder & FileName & Str$(pageNo) & ".pdf", _
        ExportFormat:=wdExportFormatPDF, _
        Range:=wdExportFromTo, From:=pageNo, To:=pageNo, UseISO19005_1:=True
     On Error GoTo 0
  Next pageNo
  Exit Sub

'Error Handlers
  MsgBox "There was a problem saving your PDF. This is most commonly caused" & _
   " by the original PDF file already being open."
  Exit Sub

End Sub

It took me about 10 minutes to plan this out, 10 minutes to make the list, 10 to find the macro and edit it, another 3 to fine tune, and about 10 minutes and about $45 to place the order.  For that I get customized, unique, cheap gifts for some of my best friends, and about 1/3 of my remaining shopping done.


Wednesday, November 29, 2017

How to say no ... 2017 Edition

RochesterBestiary detail Griffin

Thanks goes out to Brett Marquard for suggesting this update!

Negation has always been a beast of a problem.  In 2011 I described a bestiary of negated concepts used in CDA, and how to relate them using the standard.  As time goes by and the standard becomes more widely used, our understanding of the best practices also changes.

So here is the original bestiary with links to examples to the CURRENTLY ACCEPTED best weapons for slaying these beasts when known and provided by the CDA Examples task force.  And I'll be posting a link to this post in the original.

  1. Patient is not on THIS drug.
    Example pending, check back in a bit
  2. Patient is not on ANY drugs.
    No Medications.
  3. Patient does not have THIS ailment.
    No Known Problems
  4. Patient does not have ANY ailment.
    No Known Problems
  5. Patient does not have THIS allergy.
    Example pending, check back in a bit
  6. Patient does not have ANY allergy.
    No Known Allergies
  7. Patient does not have ANY MEDICATION allergy.*
    No Known Medication Allergies
* New in this edition

Examples for all of the above and more can be found at


The subtle differences between data needed for different use cases

As a patient, I want to be able to look back at my medical history and understand what the situation was as I saw it at the time.  When I'm referred to another provider, I really only want to talk to them about the situation that I'm experiencing in the now, and for the most part, they only want to see the relevant and pertinent parts of my historical situation as it relates to now.

This creates subtle differences in the views needed to create clinical documents for these two use cases.  The HL7 Continuity of Care Document using CCDA 2.1 can work for both use cases, but the content to include varies.  Preset document formulations will almost always break for some use case.  Customization is essential.

Resolved issues and completed medications are LESS likely to be relevant in the referral case, than the historical view. In the historical view, I want to see the medications that were being used at that time (e.g., metaprolol).  In the referral case, we are likely to only be talking about my current medications (amlodipine/benzapril).  In the historical view, I'll be looking at resolved problems (cervical radiculopathy) as well as those that are still currently active (e.g., my hypertension), but for the referral, we'll probably only be discussing what is current.

What is relevant and pertinent? It depends on your use case, and it means that you have to pay attention to it closely.  It even varies according to the reason for referral.

It gets even more challenging once you start to bring payers into the picture.  What can you share with a payer?  While minimum necessary is the guard rail, there's NO crisp white line.  Can historical data be shared that preceded the payer's relationship with the patient?  I've heard arguments for both sides of that case.

Dynamic query through FHIR based interfaces can help a great deal in these scenarios.  The requester can simply ask the questions (remember Query Health?) they need answered.


Monday, November 27, 2017

It's not real

I took a doctor to task over the weekend after he admitted that he didn't believe in a diagnosis of Fibromyalgia.  I told him it didn't matter to the patient what the problem was called, it was real and of concern to them, and that he needed to read up on it and learn more.  That, as an ED doc, he wasn't qualified in the appropriate specialty to make the determination about the reality of the disease, and that he needed to focus on what was happening to his patient, not what someone calls their disease.

He actually thanked me.  I hope he actually does something about it.

--   Keith

Thursday, November 16, 2017

Data Philosophy and Game Theory

It's Dirk Stanley's fault.  He asked on FB:

#CMIO #CNIO #Informatics #HealthIT and other #ClinicalJedi, need your help : Philosophically, which is more important? 
1. Data in
2. Data out 
3. Both are equally important 
All opinions welcome.

My response was pretty straightforward:
Data in, else we would not be where we are today. We need data to act, and can always get it ourselves, and trust it better when we do. But, if all are playing for optimal payoff, it could be viewed as a zero sum game, and so best view is both.

But at the same time it needs a heck of a lot more explanation.

Data sharing as presently practiced by healthcare organizations is in some ways a zero sum game, and in some ways not.  

It's not a zero-sum game for healthcare organizations. The lack of accessible data used in healthcare decision making results in efforts to obtain data. With current practice (fee-for-service), the healthcare organization will do what is necessary to obtain that data (order the test, do the assessment, et cetera).  And it will get paid to do it, so there is little to no additional cost.  For some of the testing, there is little gain (many lab tests are low-margin, commodity items), and others substantial gain.  For example, an MRI can cost $1-3K or even more, and when all is said and done there is definite value going to the creators of the data.

The data, thus gathered, also becomes an asset of the healthcare organization which gathered it, which has value to the organization when they use it, but could help a competitor in some way if they share it.  Sharing that data with a competitor has a cost. The organization has little to gain by the sharing of that data, and something to lose (potentially) if they access data shared by another party.

Victor Dubreuil - 'Money to Burn', oil on canvas, 1893There's a money to burn in this system. Between healthcare organizations, it isn't a zero sum game. The patient (or their payer) is continuously pumping in cash to the system to fill the data needs of the healthcare organization, and which supports the care of that patient when they stay within the same organization.  As soon as the patient moves to a different healthcare organization, they lose the value of that data, that ultimately, they (or their employer) paid for.  

Where the zero-sum part comes from is that what the provider gains with regard to acquiring data, the patient (or their payer) loses. As long as that remains the case, there's little incentive to reduce duplicate testing.  I watched this recently as a young person I know went through a month repeating almost the same tests they had gone through previously to diagnose a chronic illness because more than 3/4 of the way through that process she was forced to change healthcare providers (due to a forced change in health insurance).  There was NO reason for them to refuse the additional testing (getting the diagnosis is critical to their health), and no value for their new healthcare provider to use the previously performed tests. Their payer was out the money for the repeated testing, even though those tests had been done previously.

In the rest of the world of business, when I pay for something to be done, I own that thing. If it a work of intellectual property, I paid for it, I own it, and I have easy access to use it. In healthcare, when a patient pays for a test (or a payer pays on their behalf), the data is treated as if it is owned by the organization that ordered the test (gathered the data), and as the patient I don't always have easy access to it.  I can only benefit from it as long as I maintain a relationship with that healthcare organization.

I can see how game theory could be applied to this situation, such that a system of value-based care could be designed where the greatest value is when there are incentives for data sharing.

Wednesday, November 15, 2017

Understanding and addressing technical debt

Architects and accountants have something in common, which is that they need to understand their organizations assets and liabilities.  For an accountant, these are fairly understood.  For an architect, one might think that they are as well.  Your assets are you IP and processes that add value, that enable your organization to out-pace its competition.  And your liabilities are those that don't.  We have a special word in architecture for IP liabilities: it's call technical debt.

Technical debt is a great opportunity for architects to benefit their organization, and here's why: it's something that is already costing your organization in terms of resources and credibility.  You can probably count the defects in the package, the tech support calls raised, the number of open customer issues that  are due to technical debt. You can put a very clear value on it, which makes it a great candidate for reducing cost.  It isn't free, but it is often quite worthwhile.

How do you do it? It's pretty simple -- pick a mess and clean it up.  I don't just mean pick the stuff up off the floor either, like your teen would clean their room.  At the very least, polish it like a fourth year recruit at West Point.  At best, remodel, and I mean completely remodel or rebuild -- like Grahame Grieve did for HL7 Version 3 creating FHIR.  The corollary to "if it ain't broke don't fix it" should be "if it keeps breaking, stop fixing it and replace it."  When car repairs exceed the cost of payments, it makes sense to get a new car (unless you are talking about something like a 69 Pontiac LeMans*).

It's painstaking work.  Usually messes like this accrue because code becomes fragile, knowledge gets lost, nobody knows quite how that works (or doesn't).  And yet there is still some underlying value to the code because it does something important and cannot be otherwise expunged, so some extra effort is needed.  It's like the antique in the attic that just needs the right refinishing to become an awesome heirloom.  This is frustrating work, often risky, and sometimes it's downright boring  and tedious (ever read through nearly a thousand different logging messages).  On the other hand, the value of the work can be made very clear and well defined.

The biggest challenge you will run into in trying to take on work like this are people who are concerned about the risks you are taking on. The biggest tool you have to combat risk is knowledge, and sometimes that means making the time to obtain more. The most fragile software components are usually the ones where the least is known about them. Go learn it. In the end, you'll be glad you did, even though getting it finished wasn't the most glorious thing you've ever done.

  -- Keith

P.S. As a teen, I spent the better part of a winter replacing an engine in a 69 Pontiac. It was cold, it was hard, it sucked.  It was my ride to school, and I learned a ton.  It looked something like the picture below, but was black.