Tuesday, December 19, 2017

Burning up IHE Profiles with FHIR

QEDm, PIXm and PDQm finished in one day!  I'm ready for the IHE North America Connectathon in record time.  It's a shame I haven't signed up for some of them.

In part, I already had most of this coded, since QEDm and PDQm are really just simple IHE wrappers around existing FHIR resources.  But what really simplified this for me was the HAPI support for translating STU2 FHIR resources into STU3 FHIR resources.  I could rather simply call on my existing code to do the work in STU2, and the translate the results to STU3 using the HAPI FHIR Converter.  Kudos to the HAPI team for making that transition so easy.

The other piece that simplified a great deal of this is that I only needed to code up one resource for QEDm, and then write the code generator.  After that, the remaining QEDm resources were quite simple.  And then I realized I could use the same code for PDQm, which grabbed me another profile quite unexpectedly.

Not to be outdone, I decided I'd add a little extra work in and do the work for PDQm.

I might have to take the extra time I'd allocated myself for this task and toss of MHD as well, but I think I'll focus some attention on integrating CQL first.  That could take a solid week, but I promised myself a good scotch if I could get it done in two days.


Thursday, December 14, 2017

The Hero's Journey as the Patient's Longitudinal Record in HealthIT

Clinical documents tell stories, but the clinical document is not a book by itself describing the full story of a patient's care.  It is merely a single chapter, or perhaps just one scene in a chapter related to the life of a patient.  Over the course of a single illness, several chapters will be needed to make the book describing the course, or even several sequels covering significant events in a series.  Over the course of a patient's life, many such stories will be told in that milleau, making up the patient's biographical health library.

As an informaticist and informatician I'm interested in how one would classify these relationships and how that would be implemented in practice.

The metaphors that I've already started with provide an operational framework in which we can place a clinical document, and so, organize our patient libraries.  While metaphors are great teaching tools, we must also relate these terms to our own terms of art in Health IT, lest they be misunderstood.  The table below is one such mapping.

bookepisode of care
serieshealth concern
milieudisease process
librarylongitudinal record

* sequel is intentionally left out, but will be addressed in Series below.


A scene occurs within a specific time period, has a setting, involves different people (the patient, healthcare providers, family members, et cetera), and tells the story of an event (service event) occurring in the life of our hero (the patient).  The hero may not even be present in the scene (e.g., as in a lab test) but the scene is still relevant to them.  The scene is represented in a clinical document which describes the setting, the time frame and the cast of characters involved, including their role, describing this service event.  This is a document, and has all the defining characteristics thereof. 


I represent a chapter as an encounter.  A chapter ties together several scenes, in closely related time periods, and these are closely associated with some sort of common progression of the story in time.  Clinically, the encounter has many of these same characteristics.  An encounter can result in several clinical documents (scenes), in which the patient receives multiple services (e.g., a consult, a lab result, a diagnostic test and treatment) described in different documents.


I use book for episode of care because the defining characteristic of a book is that it has a resolution that indicates a significant change in the story being told.  The resolution may in fact be the conclusion of the overall story, but often simply represents a change in focus, for example, from onset to diagnosis, diagnosis to treatment, or from treatment to recovery.


The series represents the overarching story in which our hero is engaged.  It is the hero's journey, through various acts (books).  This journey addresses the crisis introduced in the first book of the series, and brings it to a satisfactory (though not necessarily final) conclusion.  Unlike a book, which may leave you hanging, a series brings you to a place where you can stop for a bit, and the tension has been resolved back to an acceptable (though not necessarily starting) state.  In the patient's life, this seems to be best represented as a health concern ... the crisis around which the series resolves.  Series are organized in time, where each book in the series is a sequel to the prior one.  Essentially, each new book is the story of the sequelae related to the prior one.


Our hero's story may not be over.  Odysseus's concern, the Trojan war as told in the Iliad, has a followup ... getting home afterwards in the Odyssey.  The patient's story doesn't end after treatment ... there's also recovery.  The health concern changes over time, but the milieu remains the largely same, and is related to the disease process over time.  I had originally considered specialty as the mapping for this, but I'm finding that specialty changes as one traverses from diagnosis to treatment and recovery.  In the case of my mother's heart attack, the specialty changed from ED, to cardiology, to rehabilitation of the course of her disease.  The health concern also changed.  But what remained common was the disease and recovery process.


All of these are components of the library that tells us the life story of our hero.  This is the one thing in common throughout this lifelong journey.  This is the patient's "longitudinal record."

Having provided the metaphor, I will shortly show how we can put this into practice in an XDS Registry or FHIR DocumentReference metadata describing our hero's journey.


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("os.name", "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 moo.com, 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 moo.com.  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
'SOURCE: www.TheSpreadsheetGuru.com/the-code-vault

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.