Friday, July 28, 2017

One Network, Multiple Carriers

Can you remember the days when having a phone meant you could only talk to people who used the same phone service as you?  Probably not.  By the time I was even born, this was already long on its way out.  It took some time to break the monopoly up, but it did happen, so we could even show that you didn't have to have everything under the same roof.

Carequality, SureScripts, Commonwell, DirectTrust, Nate, various HISP vendors ...

These are the names of organizations deploying the on ramps to the patient health information network.  The carriers if you will.

Already Carequality and Commonwell have announced that they are bridging between their networks.  HISP to HISP connectivity was built into the Direct protocol, but to fully make it work, we had to have trust frameworks ... e.g., Nate and Direct Trust.  There's still concerns that some Direct networks cannot talk to each other, and we sure as hell still have a problem with our "phone books" (the directories of provider addresses).

Let's go broader.  Let's make sure that we can have the carrier of our choice, but can access anyone anywhere.  Let's make sure that the network connecting patients and providers is a true network. Let's make finding how to connect to any provider as easy as it is to find them on Google.

Otherwise, we might as well spell network with two o's.

   Keith

Thursday, July 27, 2017

What is an (Open) API?

Open-APIs-v5My wife asked me what an API is the other day. APIs are clearly all the buzz in Health IT, just ask Don Rucker.

What is an API?  First, let's decode the acronym: Application Programming Interface.  OK, that's a mouthful, I see why we shortened it.  Basically, an API is stuff people use to write programs.

Can you name some early examples of APIs in the IT Industry?  How about POSIX, or the XML Document Object Model.  Depending on what millenium you entered the field of software, even the phrase API can be a bit nebulous.  To a C or Pascal or FORTRAN programmer, it is the collection of functions and procedures that you can call to effect some activity on a computer.  C++ and Java folks will understand it as a collection of classes and associated methods that you can use to do stuff. JavaScript, Python, Ruby, Perl ... every programming language has these things.

A "standard" API is one which is well defined, having a formal specification.  POSIX was great in early years of computing when cross-platform code was a real challenge.  We needed the ability to write the same program and have it be able to be compiled and run on a Unix system, a MacIntosh computer, or an IBM PC or compatible system.  POSIX was limited to operation in a programming environment using the C programming language (it was tightly bound to the C programming language, and used C syntax and conventions in its definition).

Today, we work in a plethora of different programming languages.  I use C, C++, C#, Java, JavaScript, HTML, XSLT, CSS, JavaScript, and a host of other special purpose languages, and when I need an API, I want one that works in whatever language I happen to be using at the time.

An Open API is one in which the standard is readily accessible to anyone who wants to use it.  That isn't to say it was free, just readily accessible ... usually the price of a text book.  But to use it you also had to have access to a compiler to build code, but that wasn't a huge issue for most developers, just already part of the cost of doing business.

The first really "free" API I spent any time with was probably the W3C Document Object Model Release 2 (DOM).  While my computer wasn't free, anything I needed to write code using the DOM was (Mosaic and the specification itself).  But frankly, the text book was still useful to teach me how to use it.  DOM was also one of the first APIs I used that had well defined formal bindings to multiple programming languages, including C++, Java and JavaScript.

My example APIs above are not RESTful, although that is often assumed in the case of APIs in modern discussions about them.  An API could also involve other protocols to access objects and methods, such as SOAP, or CORBA or COM (ActiveX).  These are access protocols to APIs, more than they are APIs themselves.  An API need not be bound to a single access protocol or programming language.  Other protocols can also be used, some involve message passing, and other kinds of exchanges.

Open is another interesting word, especially applied in the context of open standards.  If the information about the API is readily available?  To some, all that is needed is a readily available formal specification, but to others, it must be a specification to which not only access to use, but also access to participate in the development is readily available (which implies access to standards setting processes).  And cost is potentially an issue here. Ownership as well.  Microsoft owns COM and ActiveX.  Are they standards? Maybe by some definitions, but not by currently accepted definitions in many countries.  Personally, I prefer the meaning of open that means a) free, and b) that I have the opportunity to participate in its development if I so choose (although I can accept that might have some costs associated with it).

HL7 Version 2 is a messaging standard, and because it is freely available, might also be considered an open standard.  Is it an API?  I would have to argue that it isn't an API by itself, because it misses an essential feature in its specification, which is the expected behavior.  An HL7 V2 ADT A01 message that is sent to a receiver doesn't have any defined behavior according to the HL7 specification.  It just has a trigger event and a bunch of data, and the receiver is free to deal with it as it sees fit.

The receiver could use an ADT A01 message to register a patient, or it could use it to send a message to a housekeeping system that would cause someone to be scheduled to transfer a patient from admissions to a room, or it could communicate a new admission to a care management system then activated someone at the patient's payer to begin the care coordination process for a patient.  The expected behavior here is implied, but unspecified in the HL7 V2 specification.

However, apply that same message to a use case with behavioral requirements o a system upon receipt, using for example, the IHE PIX or PDQ profiles, and now you have a defined behavior occurring.  The receiving system is expected to behave a certain way.  If you have some IHE background, you'll also be aware that PIX and PDQ have HL7 V2, V3 and FHIR variants.  These are basically bindings of the PIX/PDQ behaviors to various syntaxes using messaging or RESTful APIs.

It's one step removed from a programming language, unless you call writing the message syntax itself a language*.  Formally, it is a language, informally, if you have to write code that way, get a better job.  It is definitely a protocol, and often I can translate a protocol into an API with very little effort. I don't usually write messages directly because the syntax is usually too complicated for me to remember where everything goes (although I can do that with FHIR).

Using the above example, is the Direct Protocol an API?  Kinda, but even less so. I also have to pick bindings for message sending and receiving via an edge protocol (POP, SMTP or MAPI), and also do some weird stuff in ASN1 to do DNS lookups.  The reality is, it might be, but I frankly would never treat it the way I do.

What's my answer?

An API is a formal definition of a programming interface, that defines the types of information to be used, the names of the operations that can be performed in that information, and the behaviors that can be expected, which has a defined way of writing a program that tells a computer how to make (usually cool) shit happen.  The essentials** of how you write the code (given a particular programming language) don't vary.  If network communications are part of the API, the essential content won't vary.

An Open API is one I can freely use.

Open protocols are like open APIs, but the essentials of how you might write the code can vary depending on what other tools you have available.  The network trace of communications won't vary.

For me, FHIR is probably the best, but not only example of what an Open API is in healthcare. Several IHE profiles or HL7 Implementation guides might also be considered, but might also be thought of as Open protocols.

   -- Keith

* I have in fact used telnet to a TCP port to write an ADT message directly to a receiver on multiple occasions.
** By essentials, I mean the interpretation of the program by the computer.  The names might change for variables and such, but the meaning and behavior is always the same.

Tuesday, July 25, 2017

Ring of FHIR

Interop's a burning thing
And it makes a fiery ring.
Data we desire
So I coded up a ring of FHIR

[2x]
We coded up a burning ring of FHIR,
Resource 1, 2, 3 and the flames went higher
And it burns, burns, burns,
The ring of FHIR, the ring of FHIR.

Data tastes so sweet
When patients and you meet.
We played with you like a child,
Oh, but the FHIR went wild.

We coded up a burning ring of FHIR,
Resource 1, 2, 3 and the flames went higher
And it burns, burns, burns,
The ring of FHIR, the ring of FHIR.

We coded up a burning ring of FHIR,
Resource 1, 2, 3 and the flames went higher
And it burns, burns, burns,
The ring of FHIR, the ring of FHIR.

And it burns, burns, burns,
The ring of FHIR, the ring of FHIR,
The ring of FHIR, the ring of FHIR.



Monday, July 24, 2017

Code Once, Cloud Anywhere

One of the challenges with Cloud is that there are many new paradigms to deal with and every cloud provider wants you to use their own custom APIs for connecting an enterprise to a cloud.  We know what happens there.  You get locked in to doing things the way that one cloud vendor does it, and then you wind up being stuck when you need to work with a different cloud vendor for something else.

With cloud computing becoming so much more ubiquitous, the idea that you are going to be able to work with just one Cloud vendor is stretching things just a bit thin. 

What I want for my interfaces is code once, Cloud anywhere.

Building an infrastructure that doesn't take advantage of all of the bells and whistles of ones chosen cloud provider has its costs (usually in terms of performance and developer efficiency).  But rewriting code to switch or add cloud providers has a cost as well (often in terms of lost opportunities and delays).

Microservices will help greatly as long as they are truly "micro" and have limited dependencies.  But there are cases where you just don't want to hide the power of your cloud infrastructure (e.g., queries to document storage) from your enterprise endpoints accessing data in the cloud.  That's where standards should help.

One way around this is to utilize standards but you have to look at things just a little bit differently when you do this for Cloud ... because you are typically working at a different level (often both lower and higher) than you would for applying application standards.

These are some of the areas I'm looking into standards to apply for use with Cloud, along with standards that I've managed to identify.  Granted, this list is very weak, but I've also only just begun this exploration.

Security
Encryption (TLS)
Authentication (OpenId)
Authorization (OAuth 2.0, SAML)

Operations
Audit (also fits under security)
Telemetry and Monitoring

Communications/Transport
Messaging (AMQP)
Document Storage (JSON, MongoDB API)
Blob Storage (S3)

So, if you have any thoughts about standards that should be applied in cloud computing, I'd be happy to hear about them in your comments below.


    Keith

Thursday, July 20, 2017

Date queries as offsets from now in FHIR

It's fairly common to ask questions about time in relationship to now.  Have you had a mammogram in the last 12 months?  What medications was the patient given today?  What are the labs for the last 30 days.  Can we schedule a visit for a month from now?

When a date query is expressed in the form of a simple quantity, there are two pieces of information given: A value, and a unit of measure in duration.  When expressed as FHIR queries, a date and a simple quantity are quite readily discernible.  Dates have -, : or T punctuation in them.  Simple quantities have units and | punctuation.

So I decided to try this out mentally.  One of the challenges is dealing with precision.  If someone asks me what I've did last month, I'm thinking June.  If they ask me what I've done in the last month, mentally I'm thinking July and the end of June, because I mentally translate to 30 days or so.  But then if they ask me what I was doing more than a month ago, I go back to thinking in one month chunks, so before June.

I decided that units specified in the query would also specify the units of precision.

I adopted the convention that a date query parameter named "date" would have an alternate way of specifying it using the name "date-fromnow".

So, if you query from date-fromnow=le-1||a what you would be asking is "what happened in the year before the last one." That's equivalent to date=le2016.  If you wanted more precision, you could ask in months or days (weeks are a bit messy, so I didn't deal with them).  Thus, date-fromnow=le-12||mo means date=le2016-07.  And date-fromnow=le-365||d means date=le2016-07-05.

Good enough.  Time to go implement this and see how it pans out.



   Keith

P.S. For what it's worth, this is quite useful to implement some of the guidance in the Relevant and Pertinent work that was done=-1||a.

Wednesday, July 19, 2017

How do you write a blog?

I get asked this question a lot.  The answer of late is that I haven't been, but I'm getting back into it. This is my fourth post in five days, back up to my previous rhythm when I was at top of form.

There are three big issues:

  1. Time
  2. Topics
  3. Trepidity (bordering on Terror)

Time

Where do you get time to write?  A lot of the topics I write about are things I'm already spending time on.  Taking what I'm working on and turning into a blog post is a lot easier than writing a post specifically for this blog.  It takes 10-15 minutes, and in the end, I have more clear thinking AND a blog post.  
Allocating time to write is critical.  It doesn't need to be at a fixed time each day (or week or whatever frequency) is important.  It takes discipline.  Make the commitment, and then execute. 

After you've been repeatedly writing a post on a regular rhythm, you will find it takes much less time. When I first started this blog, I might have spent an hour or even two on a post.  These days, it takes much less time.

In summary, use what you are already doing, make the commitment, and give it time to improve.

Topics

I get my topics a number of ways: Standards projects, mailing lists (a good e-mail response to a list group can also be a good starting point for a blog post), news articles, my Ask Me a Question page, and sometimes, just staring at a blank screen.  When a good topic comes to mind, I write it down for future use.  I don't have a big future pipeline, maybe one or two ideas at most.


Yesterday's post on Building Blocks was essentially me thinking out loud about my position on interop building blocks.  I took an item I was already working on for my own needs and repurposed it for something else.  The post on vocabulary started from an email on an HL7 list.  This post today started from a question someone asked me that I've had asked before (always a good sign that a blog post might be warranted).

That blank screen is is a challenge.  Some days you'll be in that time for writing a post, and have NO topics.  I just start writing and see where the flow takes me (those are usually tagged Rambling).

Trepidity

Not really a big issue for me, never was.  But I understand performance anxiety, and writing a blog is kind of like performing. The basic issue is that you need to finish strong. In any performance, the audience may notice a small bobble, but the reality is that if you finish well, few will remember your mistake, and most will remember your finish.  Don't be afraid to make a mistake. That's how you learn.  Fix it and move on. People will remember the good stuff.  If you write a terrible post, write a better one next time.  If you stop writing because of a terrible post, the first thing people will see is that post on your blog.  Write another one.

A blog doesn't need to be great, it just needs to consistently good. The best way to get there is to do it.


Tuesday, July 18, 2017

Building Blocks

If you are like me, you probably had a number of different "construction" toys growing up.  I had Tinker Toys, Lego blocks, Lincoln Logs and an Erector set.  In fact, I still have the Lego and Erector set, although they don't get much use any more.  Mostly because I get enough time to construct cool stuff for my day job.

I ran across this video this morning.  You can probably relate.


These are my building blocks today:

  • CDA Templates
  • FHIR Resources (and Argonaut Profiles of them)
  • IHE Cross Enterprise Document Sharing Family of Profiles
    • XCA, XDS, XDR and XDM
  • IHE Mobile Access to Health Documents (MHD) [Basically a FHIR replacement for the above]
  • SMART on FHIR
  • OAuth2
  • TLS
  • IHE ATNA
  • FHIR Audit Resource
I've done CDA to FHIR transformation and visa versa, CDA to XD*, XD* to MHD and MHD to XD*, and mapped ATNA to the FHIR Audit Resource.

I have the "adapter kit", and I've also built some adapters for X12 and HL7 V2 (a whole chapter of the CDA Book is devoted to V2 to CDA transformation, and I've also done the reverse).

Each of these "building block kits" has a slightly different way of doing things, but since they were built incrementally, usually with knowledge of at least one predecessor, there's some clear backward compatibility built in [although not exposed to those unfamiliar with the history of these works].

If you want to put wheels on something, there's a Lego way to do that, or a Tinker toy way, or an Erector set way (I haven't really figured out how to do it with Lincoln logs yet), and the same is true for my "adult set" of toys.  And just because I can do the same thing with both, the amount of effort invested varies.

FHIR is extremely promising as a way forward, because it continues to incorporate the learnings from previous efforts.  But we aren't all the way there yet.  I have a significant investment in Lego, and it's wickedly cool and easy to put together.  But it doesn't quite have the strength to span long distances with great weight reliably and at the same cost per piece the way that an erector set does (but I suspect it will get there).

  1. Will we get there?  Eventually I think we will.  
  2. But we've also had Highlander for 30 years.  Have we reached only one yet?  No.
  3. Is it going to happen soon?  Yes.  
  4. Soon enough to make everyone happy? Surely not, because that would have meant we had reached that point a decade ago.







Monday, July 17, 2017

The Vocabulary of Vocabularies for the non-Vocabularist

In informatics and health IT standards circles we talk about Ontology in a way that assumes that everyone understands what that means.  Yet the ontology of ontologies is rather complex and confusing, in part because definitions are in some ways, rather "meta".

What follows are my own definitions, written to be intelligible to a software engineer without informatics or health IT standards training.


TermDefinition
TermA word or phrase describing a thing, and associated with a concept (see Concept)
Preferred TermDifferent words or phrases can be used to describe the same thing.  A heart attack can also be described as a myocardial infarction.  The preferred term is the term for that thing that is preferred above all others.  Preferred terms are often those with the most "crisp" meaning (e.g., Myocardial infarction in the above example).
ConceptThe abstract idea associated with a thing.  This is the idea that is (intended to be) brought to mind when one uses a term to describe a thing.  A good concept has a definition associated with it that allows a user to understand the meaning of it.  In my not so humble opinion, the position of a term in an ontology is an insufficient definition because it is only intelligible to those well versed in the structure of the ontology.
CodeAn identifier associated with a concept.  It is a string of symbols (usually digits, but also can include letters and punctuation) that uniquely identifies the concept within the system using that code (see system below).  Codes can be meaningless (e.g., as used in LOINC), or can also express structure (usually hierarchy) as in ICD or the Healthcare Provider Taxonomy.
Check DigitA digit or character in the code used to enable verification that the string used as a code is valid and is not the result of some sort of data entry error.  Check digits prevent various kinds of data entry errors including deletion, insertion, and transposition.  LOINC uses MOD10, and SNOMED uses Verhoeff algorithms to compute check digits.
VocabularyA collection of terms describing things.  A good vocabulary has both the terms, and associated definitions of what those terms mean in a way that the users of that vocabulary can understand the meaning.
Value SetA managed collection of terms describing related things and associated with some sort of identifier so that it can be referenced. A value set most often contains terms from the same vocabulary system, but might include terms from multiple vocabulary systems.
HierarchyAn arrangement of things into a tree structure, such that each item (except the top-most) has exactly one parent.
Poly-HierarchyAn arrangement of things into a directed graph structure without loops, such that each item in the graph (except the top-most) has at least one, and can have more than one "parent". There may be multiple top-most items.
ClassificationA vocabulary that describes all the different things that can happen such that the description of any one thing fits into one and only one bucket.
TaxonomyA hierarchical classification; A classification that also has a tree structure associated with it.
TerminologyCustomarily, a terminology is a collection of vocabularies that can describe multiple related things.
SystemA phrase appended to code, vocabulary, classification, taxonomy, terminology or sometimes ontology.  The word system implies a process or method associated with the work. When this word is used, it implies a degree of formality associated with the development of the work.
OntologyIn this context, an ontology is a classification system that describes not only a collection of things, but can also describe the parts of itself.  Under this definition, SNOMED CT is an ontology, and so is LOINC (because some LOINC parts describe LOINC itself), but ICD is not.

Friday, July 14, 2017

Wearing Many Hats

When I first started working with ANSI/HITSP over a decade ago, one of the things I remarked upon to several people was the outstanding ability of John Halamka to wear many hats, and to make it clear which hat he was wearing when he was speaking, and his general ability to be wearing the right hat for the right audience.

It's a tricky challenge, and quite a juggling act.  I don't do it nearly as well as John does, but have been doing it a great deal over the last 18 months.  These are just a few of them in approximate rank order based on time investment (though not necessarily personal preference):
  1. Patient Advocate
  2. Architect Owner
  3. Product Owner
  4. Subject Matter Expert [Health IT Standards & Regs]
  5. Informaticist
  6. Software Developer
  7. Engineering Manager
  8. Thought Leader
  9. Student
  10. Teacher
  11. HL7 Board Member
  12. HL7 Member
  13. IHE Member
  14. Document Writer


I often find my various hats being at war with each other.  My software developer side wants to argue with my SME side, or sometimes I find my IHE side needs defending from one of my HL7 roles or ...

When that happens, it is very challenging to understand how to resolve the problem.  The pragmatist and the purist at war is not pretty.  Purism has its place, as does pragmatism.  Perfect is the enemy of the good goes to battle against applying the time to do it right as compared to the time to do it over.

How do I resolve this?  I've begun to discover that the final hidden role is that of customer advocate. That jumps to number 2 on my list.  Where Patient Advocate cannot break the tie or bring peace, Customer Advocate often can.

What roles do you play?  How do you reconcile them?