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.

Thursday, January 18, 2018

CQL for Me, or what not to do at an IHE Connectathon

If you think you are going to implement a brand new feature during Connectathon week, then you probably are about as brain dead as our poster child for accidents waiting to happen on my right.  Having said that, my job for this week is to at least get started on implementing a clinical quality language execution engine into my FHIR Server.

So much for brains, right?  One of the biggest challenges I've had is that while there's plenty of open source implementations out there, there's not a whole lot of documentation on how to use them.  And while as a language, CQL is certainly easy enough to read, there's some very basic assumptions about a programming language that are left completely unstated in the standard.

"What does hello world look like in CQL?" is one of those questions that I hadn't found (nor could Google) anyone addressing.

That's a really good question.  The answer isn't to be found in the CQL Specification, but I did eventually figure it out.  It looks like this:

define result: 'Hello world!'

Pretty simple.  The execution of a CQL program basically produces a list of results, where each result has a name and a value.  This makes it really ideal to use a JSON representation for output, by the way.  There's also a type (associated with the value), and a location associated with the definition that you can get out of the engine I'm using (which makes it really handy for debugging).

This was my DUH moment last night.  Now it doesn't have to be yours.  I think I'm about to join that open source community as a doc writer (at least to start off).


Tuesday, January 16, 2018

Converting STU2 to STU3 in HAPI on FHIR

AC Converter Adapter USA-EU
So, you've built your HAPI FHIR Server, and if you started when I did, you may have even started with STU2.  But these days IHE profiles are in STU3.  What's a guy to do?  Well, if that guy is an engineer, the first thing you WON'T DO is rewrite your server from scratch.  For PIXm, PDQm, QEDm and likely even MHD (although I haven't checked that profile out yet), the simple answer is to front end your STU2 services with an STU3 facade.

The pattern for such a facade is fairly simple:

public class MySTU3ResourceProvider  {
  private final MySTU2ResourceProvider stu2Provider;
  private VersionConvertor_10_30 converter = 
     new VersionConvertor_10_30(new NullVersionConverterAdvisor30());

  public MySTU3ResourceProvider(MySTU2ResourceProvider stu2Provider) {
     this.stu2Provider = stu2Provider;

  @Search() Bundle doQuery(...) {
     try {
       // call the previous method and get the bundle response
       return coverter.convertResource(stu2Provider.doQuery(...));
     } catch (BaseServerResponseException ex) {
       // We got a "normal" exception from the processing.
       Object o = 
               (OperationOutcome) ex.getOperationOutcome());
             ex.setOperationOutcome((IBaseOperationOutcome) o);
       throw ex;
     } catch (FHIRException fex) {
       throw new InternalErrorException(fex);
   @Read Resource doRead() {
     try {
       // call the previous method and get the bundle response
       return coverter.convertResource(stu2Provider.doRead(...));
     } catch (BaseServerResponseException ex) {
       Object o = 
               (OperationOutcome) ex.getOperationOutcome());
             ex.setOperationOutcome((IBaseOperationOutcome) o);
       throw ex;
     } catch (FHIRException fex) {
       throw new InternalErrorException(fex);

One of the things I learned this week was that I needed to add the conversion trick to handle any cases where the original method throws something derived from BaseServerResponseException.

This is great.  Until you discover that for some reason, convertMedicationOrder hasn't been implemented, and you need to turn your previous MedicationOrder into a MedicationRequest.

So, buckle down and write convertMedicationRequest(), or use the code I wrote below.  Here's how I started: It took me about 3 minutes to find that the code had been commented out.  It took me another 15 or so to code it up, and a few more to test and tweak it.  All told, about 30 minutes. To skip to the chase, here's the code (it's not pretty, but it seems to compile and run):

VersionConvertor_10_30 converter = new VersionConvertor_10_30(new NullVersionConverterAdvisor30()) {
      public org.hl7.fhir.dstu3.model.Resource convertResource(org.hl7.fhir.instance.model.Resource src) throws FHIRException {
      if (src instanceof org.hl7.fhir.instance.model.MedicationOrder) {
      return convertMedicationOrder((org.hl7.fhir.instance.model.MedicationOrder)src);
      return super.convertResource(src);
      public org.hl7.fhir.dstu3.model.MedicationRequest convertMedicationOrder(org.hl7.fhir.instance.model.MedicationOrder src) throws FHIRException {
      if (src == null || src.isEmpty())
        return null;
      org.hl7.fhir.dstu3.model.MedicationRequest tgt = new org.hl7.fhir.dstu3.model.MedicationRequest();
      copyDomainResource(src, tgt);
      for (org.hl7.fhir.instance.model.Identifier t : src.getIdentifier())
      if (src.hasDateWritten())
      if (src.hasReasonCodeableConcept())
      if (src.hasReasonReference())
      if (src.hasNote())
      for (org.hl7.fhir.instance.model.MedicationOrder.MedicationOrderDosageInstructionComponent t : src.getDosageInstruction())
      if (src.hasDispenseRequest()) {
      MedicationRequestDispenseRequestComponent dr = tgt.getDispenseRequest();
      MedicationOrderDispenseRequestComponent sr = src.getDispenseRequest();
      if (sr.hasValidityPeriod()) 
      if (sr.hasNumberOfRepeatsAllowed())
      if (sr.hasQuantity()) 
      if (sr.hasExpectedSupplyDuration()) 
      if (src.hasSubstitution()) 
      return tgt;


This week is all about getting things close enough.  Afterwards I get to bring the code back to turn it into production.  But I'm guessing that I'm not the only one wanting to convert STU2 MedicationOrder resources into STU3 MedicationRequest resources.  So, here you go.


P.S.  As to why this is commented out, my suspicion is that the code generator that is producing the converter from the FHIR Specification hasn't quite been tuned to deal with Resource name changes yet.

Thursday, January 11, 2018

Twenty things I've learned about the ED as a Chronic Pain Patient's Advocate

Cbh emergencydepartment1
I've been spending a good bit of time as a patient advocate for a soon-to-be family member over the last month (and prior).  There were 7 ED visits, 2 ambulance rides and 3 911 calls due to untreated pain in the month of November.  It took 3 ED visits to get a diagnosis for their acute pain (Endometriosis), and some forward motion toward treatment, and another 4 since then while waiting for follow-up visits (see The Patient is Waiting ... in Constant Pain).  We've been in 2 hospitals, and 9 ED beds, 15% of the beds in the local ED.  I almost want to start carving initials.

Here's the thing, for certain conditions causing acute, level 9 and above pain, it's hard to get a diagnosis, and difficult to get consistent treatment.  Having an advocate has been crucial to making any sort of progress. When a patient is in crippling pain, it's damn near impossible for them to have an intelligent discussion about what is going on. When, as a result of ongoing chronic pain, other issues arise such as anxiety or depression, it's damn near impossible for them to get respect as a patient. Finally, when one of your diagnosis is "questionable" (e.g., Fibromyalgia) in the mind of the doctor (even though as an ED physician they are not the specialist who provided that diagnosis), it's challenging to even get good treatment (see It's not real).

What I learned in November:
  1. Be aware that if you show up on a weekend during or after any holiday, life is going to have some extra suckitude in it.  These are busy times and this is "high season" in the ED.  If you can, call ahead, better yet, have a doctor do it. 
  2. Coming in by ambulance will get the patient into an ED room immediately, but they may be moved later (many EDs reserve specific rooms for ambulance arrivals).  
  3. Treatment for pain CAN start in the ambulance if the ambulance is appropriately staffed and willing.  My local ambulance staff are fantastic (but I also live in a town where everyone knows everyone else), others are probably good but don't know us. Our local guys called the nearby paramedics from one town over to meet them en route, and having relief start in the Ambulance is huge!  
  4. If the patient isn't dying on the table, be prepared to wait with them ... in acute pain, for some time.  Remember that the ED doc's purpose is first to stabilize you, if you are in pain but not obviously dying, and your heart rate and blood pressure aren't super critical, you are probably at a level of stable that means you won't get as much attention as you'd like.
  5. When the patient is in pain, don't be afraid to let them cry or make noise, and to keep the door open. They'll get attention faster.
  6. Wait obviously, ask for attention gently, be aware that the folks you are working with are probably crazy busy, and will work better with you if you can be gentle (if insistent) with them.  
  7. If you have a specific need, ask for it (from the right person).  A pillow, water, a straw can be gotten by just about anyone, but the doctor is the worst person to ask these for.  Turning the monitor alert off requires someone trained to do that (doctor or nurse usually).
  8. If the monitor is beeping but nobody is responding, press the call button. It's faster than asking someone.  If there's a problem with over-alerting on the monitor, get them to address it.  Monitor beeps are purposefully attention getting, which can increase patient agitation -- not a good thing for a patient in pain.
  9. Come in with a clinical, rather than psychiatric reason for visit.
  10. Know the lingo. The more you speak "medical", the better they listen.
  11. Talk about what your expectation for the visit are, and get answers about what the doctor's expectations are.  Ask for times, let them know you are seeking approximate answers so that you know what to expect, rather than precise answers, and that you know they are busy and that stuff happens.
  12. You are rolling the dice on providers to be seen.  If you have a clue about what kind of provider, or know a name of someone in the hospital you have seen before, use it, ask to see them if they are available. When the shift changes, the attending doctor and plan may change too, be prepared for that.
  13. Have the medical proxy paperwork in your hands. A power of attorney is better than a medical proxy form if it allows you to take more charge (Most proxy forms address "patient is unable", but a PoA can simply designate you with certain authority).  Introduce yourself to staff by your relationship, both personal and legal to the patient.  Use the personal first, but place some emphasis on the legal authority if you have it.
  14. Keep track of the patient records, and have them on hand, electronically if at all possible.  We use MyChart extensively because it is available through all of our providers.  If you (or the patient) can state dates for relevant events, their medications including dose, and all of their conditions and allergies, you'll get more regard from the staff.
  15. If you have a choice of hospitals, consider them carefully.  My local regional hospital is beautifully laid out with modern equipment and a new facility, but the care provided by the staff is inconsistent.  On the other hand, our visit to the nearby academic medical center left me quite sad about the state of their physical infrastructure, but the one visit made there was FAST, provided excellent care and pain relief within 90 minutes AND to a degree I hadn't seen in the regional facility.  We were in and out in about 5 hours, which for us was about three times faster than the regional.  From a facilities perspective, I'd rather be in the regional, but from a care perspective, if we have a choice, we'll go back to the academic facility.
  16. The ambulance will take you to the nearest hospital, which is NOT necessarily the one you want to go to.  If hospital choice makes a difference, consider your options carefully.  Acute pain is not always life threatening, but when it is, you want to be in the ambulance.
  17. If the patient has a wheelchair or other mobility device, bring it with you. It helps to get attention needed, and it can make getting there easier.
  18. Keep a bag packed for the visit; we now have a go bag packed.  It includes plenty of water, some form of food for snacks: Oreo cookies are a favorite, but we also include protein bars, pudding in favorite flavors, and Slim Jims. The food is for both you and the patient if they are allowed to eat something. 
  19. Include a phone charger in your go bag.  Bring your own soft fuzzy blanket and whatever else will bring you comfort.  Dress in easy to access clothing, bring an extra pair of underwear.
  20. As an advocate, know a wide variety of ways to deal with pain.  Distraction helps.  Usually by the time you are headed to the ED, you've already tried everything you know.  Here are some things I've discovered.  Deep breathing is essential. Distraction works: Tell good stories, engage in pleasant and fun conversation, have the patient tell you a favorite story. Use a variety of relaxation techniques -- techniques that have already been practiced several times work better usually. Gentle massage is good.  A warm shower can sometimes help reduce pain.  If the patient is locked in pain, is having muscle spasms only makes it worse.  Do what you can to get them to relax.  
#15 was probably the most important thing I learned in November.

Wednesday, January 10, 2018

USCDI Review

This morning I finished my first pass review at USCDI (pronounced Uhsk-Dee), a.k.a. the Common Clinical Data Set ++.  Overall, a good starter set with some decent though behind it, but I would have liked some better work on definitions.  Some of the definitions in it very well defined the phrase, but not what the originators meant by the data that would help describe the exchange requirement.

You can find the data here:
Here's my initial thoughts on each section:

Draft V1

I've already made the point that Provenance needs clarification.  I should also like to point out that there really shouldn't be that much of a distinction between clinical notes and diagnostic imaging (or other narrative) text reports.

Proposed V2

Admission and Discharge Dates and Locations: FHIR and C-CDA?  Really?  Well sure if you want to put these into Encounter resources/classes (those have everything you need).  But the most common use of ADT information in healthcare setting is notification.  Payers want to know when their patients have been admitted, providers want to know when their patients have been hospitalized.  ADT is current state of are and is being use today.  Ideally, we'd shift to FHIR but we should probably focus on the fact that this is Notification, not push/pull data for the most part.

Cognitive and Functional Status: Been there, did that, not quite but almost a decade ago.  This is honestly more a matter of coming up with the right value sets in LOINC and SNOMED than any structural problem, and those have already been determined and refined over the last half decade pretty decently.

Discharge Instructions: I seem to recall this is in 2015 CERHT standards today, why would that be delayed until 2019.  This is such a common comment, let me note the other section it applies to below:
For 2019: Gender Identity, Pediatric Vitals, Pregnancy Status, 
For 2020: Care Provider Demographics, Care Team Members Contact Information, 
For 2021: Referring Provider
Emergent: Alive Status/Date of Death, Care Provider Licenses/Identifiers, Health Insurance Information

Some other general comments:
Family History: Wow, the definition is totally crazy on this one.  Compare:
Information about all guardians and caregivers (biological parents, foster parents, adoptive parents, guardians, surrogates, and custodians), siblings, and case workers; with contact information for each.

To:  "information about the genetic family members, to the extent that they are known, the diseases they suffered from, their ages at death, and other relevant genetic information." [HITSP C83, Section],
OR: "data defining the patient’s genetic relatives in terms of possible or relevant health risk factors that have a potential impact on the patient’s healthcare risk profile." [C-CDA Release 2.1],
OR: "significant health events and conditions for a particular individual related to the subject." [FHIR STU3]

You don't need the contact info, you want the "Health History".  You aren't going to call these people because "HIPAA" (or at least as the provider understands it, not as written).

Diagnostic Imaging Reports: WHY are these (or other diagnostic reports) treated differently than clinical notes.  Puhleeze.

Practitioner Responsible for Care: That's simply a role for a care team member.  Pick a code, any single code to identify this, and the standards already handle it.

Emergent Stuff

There's a whole class of other, non-clinical documents.  Deal with these mostly as you do for anything else not structured.  That goes for Advanced Care Planning, Minor Consent, and possibly Emancipation Status.

Communication Facilitators: This is clearly a category person A dreamed up (translators) and person B added to (hearing aids), and since both were about communication, fell into this bucket.  Err, NO.  One is part of the care team (albeit with a very specialized role), and the other is a piece of durable medical equipment.  And if a provider wants to know what is needed to communicate with the patient, they should look in both places.

Reconciled Med List: Flag on an existing class, NOT a brand new class of information.  This applies elsewhere as well.

Special Instructions: A truly insignificant variation on discharge instructions.

There can only be one, but it keeps getting bigger

A long while back I wrote a series (start at post 5 in this list) about what was the Common Meaningful Use Data set and became the Common Clinical Data Set under the ONC 2015 rule.  It seems that every administration has to name things differently from the past to differentiate itself, but that only seems to sow further confusion.  The new name for this is the US Core Data for Interoperability (USCDI), and was released as part of ONC's Trusted Exchange Framework.

New to the data set are Provenance and Clinical Notes.  I was thoroughly interested in seeing how ONC defined Provenance.  Here's what I found in the current document:

Yep, you got it.  Provenance is just "provenance" and everyone is expected to understand what that means.  Now, everything I ever needed to know about provenance I learned from this guy (or this one), but even I know you DON'T say this is a data element you want to exchange and NOT define it clearly.  I'm sure ONC will pick some standard for that, or perhaps even more than one.  Fortunately, this is only the dress rehearsal, so it will be fix prior to production (or if necessary, afterwards, though I'd like to see them avoid that).

In addition to these two items, there are (way too many) additional elements proposed for 2019 (without clear use cases, it's hard to address value).  Some of these are viable today, while others really should get moved around.  The short list (with definitions this time) includes:

  • Encounter
  • Discharge Instructions
  • Family Health History
  • Functional Status
  • Gender Identity
  • Pediatric Vital Signs
  • Pregnancy Status
  • Reason for Hospitalization
Then there's another set for 2020, and 2021, along with yet another set of "Emerging" things which didn't managed to get past someone's filters for the initial listing.

This is actually good stuff, all criticism aside.  We have to start somewhere, and this set is as good as any other as a starting point.

When I evaluate these, I will look at them from three perspectives:
Ease of implementation, utility, and stability.  Many of these (such as Family Health History) are already tracked and have been done so at some level of detail since the dawn of meaningful use.  Others, such as pediatric vital signs are really just a small extension to the existing set of LOINC codes, that it shouldn't wait long at all for implementation.  Others, such as "Insurance information" have no value to providers or patients in exchange unless provider workflow changes substantially.

I've heard providers tell me: We don't care about your insurance data, because we have to verify it at every visit any way, and we can't rely on what someone else tells us.  I completely believe them, because I still have to pull out my dang card even when the provider at the other end has already received a prior auth.  The real issue is that doctor's don't often worry much about the work that staff already takes out of their hands.  OK, so we set things up to send payer information, are providers actually going to use it?  With the time that would save me on each referral, over the course of the year, I think I could press the snooze button once or twice more than usual on one day of the year.  Now, I actually do value my sleep pretty much, but I think I'd trade that one out for something else.

Anyway, It's worth reading, and I won't go into details on each one yet.  Do read it yourself, and send your comments (or mine which I will be posting) to


P.S. I've extracted the data tables from @ONC_HealthIT's US Common Data for Interoperability (part of the Trusted Exchange Framework) into a Google Sheet here:

Monday, January 8, 2018

Modeling Performance of API Servers

Most recently I've been looking at modeling the performance of my API Server.  There are lots of good reasons to have a model for your performance.  Some of them have to do with being able to predict behavior, and others with being able to see where things are going wrong.

Response curves don't follow the usually normal distribution.  For one, all response times must be positive.  Common models used for response times include Log-Normal and Erlang.  More recently I've also been investigating the use log-logistic distribution.  You might recall my previous discussions of the logistic curve, and as it turns out, it has other uses.

Here are images of the three distributions (all from Wikipedia) in the order referenced:
Log Normal


Each of these distributions has two parameters governing shape and position of the central hump. Log-Normal just has a useful shape.  Erlang models a sequence of identical processes, which closely approximates what a computer is doing. Andrew Charneski wrote a great blog post on estimating parameters for the Erlang and several other distributions, specifically as related to network latency, so I thought I would start there. After struggling with the estimating process, I took a look at other distributions and found log-logistic to be more computationally tractable in Excel (I don't use R, and don't have Mathematica or other numeric analysis tools readily available, or general competence in them). I think it also does a slightly better job for my uses, and that is backed up to some degree (see the Networking section in the WikiPedia article).  Dr. Mohan Pant wrote a great article on estimating the parameters of the log-logistic curve using what he calls the Method of Percentiles which I used to validate the estimation formulas I somewhat independently rediscovered on my own.  I was quite honestly glad to find it because I wasn't quite sure I could get away with estimating my parameters as easily as I did.  The math is a bit dense, but between it and the WikiPedia articles (and perhaps some additional Googling), someone with a decent math background can work it out.

You might ask what having model does for me, and that's a fair question.  One of the key benefits of having the model is that I can use it to compare two sets of performance results.  Estimating model parameters from performance results allows me to make some comparisons about expected application behavior that just isn't feasible with the raw results.  It also allows me to compare the performance to two implementations much better.

For example, presume that I have two choices about how to implement a particular resource.  Would you rather than I give you a somewhat lower average response time with a longer thicker tail, or would you prefer to have a lower 90% response time.

Here's a made up example of what I mean.  Consider the following two performance curves.
The red line on the left, or the green line to the right?  Both look like the do about the same amount of work under the large part of the curve before the tail, but the red line clearly completes most of its work sooner, so clearly it is the better one, right?  If you  picked the red line, you missed the clues in the line colors.  The modal response time of the green curve is clearly worse than the red line, BUT, it has a smaller tail.  

Overall, the average response time of the green curve is about 6.6 time units, whereas the average response time of the red curve is about 6.2 time units.  The green line requires less computer time (for both of us) over the long haul.  If you look at the dashed lines on the graph, they show the cumulative completion rate at a particular time.  By the time the red algorithm has completed 90% of its requests (14 time units), the green line has completed 97.5% of its requests.  The red algorithm doesn't get that far until until about 38 time units in.

Why do these curves have such long tails? Welcome to the real world.  A small number of patients have mountains of data to plow through, whereas most of the rest don't. That's part of it.  In a computer network, also, the long something takes, the more likely something else is going to cause a delay. As an API consumer, you are at the end of a long stick through which multiple computer systems play a role. Thread switching, process swapping, disk access, and network resources are constantly under contention.


Friday, January 5, 2018

Health IT Headlines for 2018

As promised, I'm following up on my easy predictions with some more difficult ones.  I'm sort of spoofing on the ending of Wait, Wait don't Tell Me, with Onion style headlines, because this is more of a wish list than a set of predictions.  Here goes:

Block Chain Finally has a Reason to be Used in Healthcare

I think this is possible in 2018, though possibly unlikely.  Most likely area of utilization will be in inventory management.  Block chain is pretty good at maintaining a ledger of things that need to be counted.  If we'd had "block chain" back in HITSP days when looking at situational awareness for Immunziations, someone would have been likely have tried to apply it, to which someone else would have said: "But block chain isn't a standard." [For what it's worth, it still isn't].  Where I see some possibilities is in dealing with accounting for stuff that needs to be managed, and immunizations might be a good place to start with that.

HIE of One actually Does Something

Here, I think we are in do or die time for HIE of One.  I see two possibilities:
  1. It adapts to FHIR and vice versa, and patients can finally access their own data in one app all together and easily.
  2. It starts to shrivel up and die.
This is one of those initiatives for which the hype is good, and the reality sucks.  The problem of the HIE of one today is NOT technology, there's plenty of technology that can make this work.  The real problem is creating a business model for it that can dis-intermediate the entrenched players, where the developers of it can still make an honest living providing a valuable service.  Some I've heard talk about it speak quite fondly of open source.  But the reality of Open Source is that someone is paying most developers to write the code.  There's an income stream funding the effort, even though the "software is free", and the effort is "donated by volunteers".  And Open Source won't pay for the essential infrastructure that will be needed to manage this. 

I don't expect I'll be able to adopt some sort of HIE of One product to access data from my current and past providers in 2018, but I expect to see some capabilities developed that will allow me to start down that path being released towards the end of the year.  I expect I'll be looking.  I had a doctor's visit today, and he and I had to sit through the painful process of me logging in, requesting my username via e-mail (which I forgot because my id was assigned to me instead of self-chosen), and finding my immunization history.  Yes, in fact, I did have a TDAP in the last 10 years, and am not due for another one till 2021.

Direct to Consumer Care Bundles

It will start with something simple, but I expect that care providers will start putting together price fixe care bundles for certain conditions, and offering them DTC just like pharmaceuticals are pushing medications. 

Do you have ___? Are you satisfied with your current treatment? Tired of having to go to three different places for all of the care you need? Come to ___, and for just $$$, we'll put you in our guaranteed treatment plan.Lots of really small print to scroll on the right hand side of the screen while the advertisement is playing regarding limitations and et cetera.

Advanced Visualization in the EHR

It's happening today, but it's mostly in demo-ware, and physicians don't understand it, and hate it or love it, and most really haven't gone anywhere.  But I'm praying that someone will finally figure out a user experience to give a physician an overview of the patient on one screen, with the ability to easily navigate to the details THEY think are pertinent or relevant.

What I kind of envision here is that someone teams up with ILM or similar and gets them to design something like we see in various Sci Fi movies, which actually gets built.

And if any of these things actually happen in 2018, remember that you heard it here first.