Showing posts with label design. Show all posts
Showing posts with label design. Show all posts

October 14, 2014

Bonnie: An Open Source Clinical Quality Measure Testing Tool

Bonnie is a new open source software tool that MITRE has developed and released in April 2014 that allows Meaningful Use (MU) Clinical Quality Measure (CQM) developers to test and verify the behavior of their CQM logic.  The goal of Bonnie is to reduce the number of defects in CQMs by providing a robust and automated testing framework. Bonnie allows measure developers to independently load measures that they have constructed using the Measure Authoring Tool (MAT). Loading the measures into Bonnie converts the measures from their Extensible Markup Language (XML) eSpecifications into executable artifacts and measure metadata.

Bonnie Dashboard Page
Bonnie Dashboard Page
The measure eSpecification format that Bonnie loads is Health Quality Measure Format (HQMF) XML. The HQMF specification provides the metadata and logic that describe the specifics of calculating a CQM. Bonnie can load the HQMF describing a measure and programmatically convert the HQMF specification into an executable format that allows calculating the measure directly from the specification. 

The measure metadata loaded into Bonnie is then used to allow developers to rapidly build a synthetic patient test deck for the measure using the clinical elements defined during the measure construction process. By using measure metadata as a basis for building synthetic patients, developers can rapidly and efficiently create a test deck for a measure. 

Once a CQM has been loaded into Bonnie, a user can inspect the measure logic and then build synthetic test records and set expectations on how those test records will calculate against a measure. This capability to build synthetic test patient records, set expectations against those records, and calculate the measures using those patient records provides an automated and efficient testing framework for CQMs. 

Using the Bonnie-supported CQM testing framework allows measure developers to more clearly understand the behavior of the measure logic, validate that the measure logic encodes their intent, and allows for multiple iterations of measure updates to be validated against a test deck. 

Bonnie Measure Page
Bonnie Measure Page
Additionally, the development of a test deck as part of measure development provides benefits after the measures are finalized. The test deck build as part of measure development can be used to demonstrate the intent of the measure though the use of patient examples included in the test deck. Furthermore, the test deck provides systems that implement the measures with a means to validate the development of their systems. This is provided in the form of a base set of synthetic patient records with known expectations for calculating against the implemented measures. Finally, the test deck could be used as a basis for the test deck used as part of the Meaningful Use certification program. 

Bonnie has been designed to integrate with the nationally recognized data standards used by the Meaningful Use program for expressing CQM logic for machine-to-machine interoperability. This provides enormous value to the CQM program and federal policy leaders and stakeholders: this software tool verifies that the new and evolving standards for the Meaningful Use CQM program are tractable and can be implemented in software.   

Additionally, Bonnie was designed to provide an intuitive and easy-to-use interface based on feedback from the broader measure developer community. A key goal of the Bonnie application is to deliver a user experience that provides an efficient and intuitive method for constructing synthetic patient records for testing and validating CQMs. 

The Bonnie software is freely available via an Apache 2.0 open source license. The Meaningful Use program makes all or parts of the Bonnie software available for inspection, verification, and even reuse by other government programs or federal contractors. 

This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. © Rob McCready, 2014.
Creative Commons License

October 8, 2014

Example of CDA limitations to interoperability: time intervals

The HL7 Clinical Document Architecture (CDA) is an XML-based markup standard intended to specify the encoding, structure and semantics of clinical documents for exchange. CDA is an ANSI-certified standard from Health Level Seven (HL7).  The CDA is highlighted as a flexible framework that can contain any type of clinical content.  Additionally, the details of the encoding of clinical data and associated aspects of that data are intentionally designed to be flexible.

That flexibility provides freedoms in various different systems' ability to export clinical data.  However, that same flexibility is an increasing barrier to the interoperability of data as systems need to import that same data.  My biggest pet peeve with the CDA and this problem is the flexibility that the CDA provides in the encoding of time intervals.

Based on clinical reason, the CDA provides the freedom to encode time intervals in eight (8) (VIII) different representations.

<low>
<width>
<high>
<low> <width>
<low> <high>
<center>
<center> <width>

This amount of flexibility in expressing something as simple as a time interval is an obstacle for any receiving system hoping to import and parse an HL7 CDA-based XML document without knowing the way that the generating system is going to express something as basic as a time interval. This permissive nature of the CDA's artifacts is common beyond this one basic example.

What is needed, and hopefully addressed in the emerging FHIR specification, is a more constrained approach to the foundational aspects of clinical data, such as how to encode time intervals.  To reach a point with more interoperability of healthcare data, analysis is needed of the presence of types of structured clinical data concepts and associated clinical codes used operationally.

I feel that the healthcare standards community ultimately needs to identify a strict and simple constrained set of ways of expressing clinical concepts that healthcare Standards Development Organizations (SDOs) like HL7 should use to constrain existing permissive and complex standards.  This could also be done to guide a stricter and simpler implementation to support interoperability via FHIR.

This could introduce significant and radical improvements in the interoperability of patient data in the US healthcare industry.  This will better enable disparate healthcare software systems to work together without requiring point-to-point coordination.  This could reduce, and eventually eliminate, these problems of point-to-point coordination that result in islands of automation.

This "loose coupler" approach will encourage HL7, or possibly new healthcare SDOs, to embrace a core set of strict and simple required attributes, over the current state of the practice using permissive and complex attributes.

This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. © Rob McCready, 2014.
Creative Commons License

November 22, 2013

Conceptual Hospital Dashboard Design

I have been neglecting the "design" aspect of this blog for some time.  To re-engergize the need for more engaging content, to put some eye-candy out... and have some fun on a late Friday afternoon… I thought I would share a shelved design for a dashboard that I developed for a COO at a notional hospital:

Notional Hospital COO Dashboard Design
Notional Hospital COO Dashboard Design
I have made several assumptions when coming up with this mockup.  The first is that quality and quality metrics would be of utmost importance to this user.  Maybe pay-for-performance programs have been adopted based on Clinical Quality Measures (CQMs), and quality issues have an immediate impact on the bottom line of the organization.  I included both a kiviat visualization for showing targets against measured results for CQMs, and a longitudinal trend for those CQMs over time.

With the disclaimer that I am not a clinician; I made some assumptions that knowing the types of procedures that are being performed, and when those procedures deviate from expected norms is something else that a COO would track.

Lastly, I am showing a design technique that Stephen Few will sometimes use to provide a non-white background to reduce eyestrain.  Having met him several years ago, I am a fan of Stephen's work.  I always like the muted background color that he tends to include in his works.

I welcome the feedback.

Kudos if you "get" the names of the ten physicians.

This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. © Rob McCready, 2013.
Creative Commons License

November 2, 2013

Visualization of ICD-10 Code Counts

This past week I have been working in the bowels of the QRDA Category 1 XML for the popHealth project that we are deploying for the Veterans Health Administration (VHA).  In the process of working with the QRDA Category 1, I had to resuscitate some of my Ruby and REXML skills that had atrophied in the past year.

This weekend, I wanted to shakeout some of my technical skills in a cleaner environment and downloaded the XML for the full set of ICD-10 codes from the CMS site.

Why ICD-10?  It is the 10th revision of the International Statistical Classification of Diseases and Related Health Problems (ICD) by the World Health Organization (WHO).  ICD-10 provides a hierarchy of structured codes for diseases, symptoms, findings, complaints, social circumstances, and external causes of injury/diseases.  The big national issue related to ICD-10 is that it will be required for expressing claims data to the Center for Medicare and Medicaid Services (CMS) starting on October 2014.

The current state-of-the-practice for capturing this coded data in Electronic Health Record systems is (IMHO) still ICD-9, the predecessor to ICD-10.  One of the biggest differences between ICD-9 and ICD-10 is the fidelity of data that can be captured in ICD-10.  In particular, there are over 68,000 distinct codes in ICD-10 as opposed to the roughly 13,000 in ICD-9.

Working with the XML file provided on the CMS site that details the ICD-10 code hierarchy, I wanted to see if I could convert the data into a format that would allow me to visualize the code counts into a D3.js example.  I figured it was good to exercise some XML knowledge outside of the complexity of the QRDA Category 1 XML.  Further,I wanted to learn a little more about the structure of the ICD-10 codes.

It is worth noting that the CMS ICD-10 XML is surprisingly easy to understand for the purposes of enumerating the full set of codes and the hierarchy.  The QRDA Category 1 XML… not so easy to understand.

What I did was to load the ICD-10 XML hierarchy into a simple Ruby program via REXML.  I created a aggregate count in a hash table of the second-level codes in the ICD-10 hierarchy by traversing the XML file.  I had to do this only at the second-level of the ICD-10 hierarchy because the sheer number of third-level ICD-10 codes broke the D3.js visualization examples.  To explain this a little more, the hierarchy of an example diabetes code down that the fourth level in ICD-10 follows:

E00-E89: Endocrine, nutritional and metabolic diseases
  |-> E08 Diabetes mellitus due to underlying condition
    |->E08.2 Diabetes mellitus due to underlying condition with kidney complications
      |->E08.22 Diabetes mellitus due to underlying condition with diabetic chronic kidney disease

So for the illustration of ICD-10 code counts, I stopped aggregating at just the second level of the hierarchy and count/aggregate codes from the third and forth levels.  Each tiny square in the illustration below represents the counts of just the second level of the ICD-10 space of roughly 68,000 total codes.

Once I had the counts of individual ICD-10 codes aggregated at second-level of the ICD-10 hierarchy, I exported a JSON file that could work with the D3.js example that I picked.  Below is a thumbnail (admittedly... illegible) of the ICD-10 code counts transformed with the D3.js treemap example.

Visualization of second level ICD-10 code counts
If you want to try and download a higher resolution image of the ICD-10 codes and actually read more of the details, click here.  HEADS UP… it is gianormous.

With the illustration, starting from left-to-right and then top-to-bottom, the sections in the ICD-10 data set that coincide with the colors in the illustration as follows.  The only confusing item is the last "chapter" from ICD-10 is the gray box in the bottom left "Factors influencing health status and contact with health services".  I think the D3.js code had to try and fit that section into the illustration.
  • A00-B99: Certain infectious and parasitic diseases
  • C00-D49: Neoplasms
  • D50-D89: Diseases of the blood and blood-forming organs and certain disorders involving the immune mechanism
  • E00-E89: Endocrine, nutritional and metabolic diseases
  • F01-F99: Mental, Behavioral and Neurodevelopmental disorders
  • G00-G99: Diseases of the nervous system
  • H00-H59: Diseases of the eye and adnexa
  • H60-H95: Diseases of the ear and mastoid process
  • I00-I99: Diseases of the circulatory system
  • J00-J99: Diseases of the respiratory system
  • K00-K95: Diseases of the digestive system
  • L00-L99: Diseases of the skin and subcutaneous tissue
  • M00-M99: Diseases of the musculoskeletal system and connective tissue
  • N00-N99: Diseases of the genitourinary system
  • O00-O9A: Pregnancy, childbirth and the puerperium
  • P00-P96: Certain conditions originating in the perinatal period
  • Q00-Q99: Congenital malformations, deformations and chromosomal abnormalities
  • R00-R99: Symptoms, signs and abnormal clinical/laboratory findings, not elsewhere classified
  • S00-T88: Injury, poisoning and certain other consequences of external causes
  • V00-Y99: External causes of morbidity
  • Z00-Z99: Factors influencing health status and contact with health services
If you are interested, you can access the JSON file with the second level code counts from my GitHub repository that I setup.

Further, you could use this JSON with several other data hierarchy examples off the D3.js site if you are interested.  They use the same JSON format for representing the data, and you should be able to just drop the JSON that I created into that HTML if you tweak the name of the file in the examples and set your width and height of the demo to about one thousand times greater than what is provided since the about of data is so large.

This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. © Rob McCready, 2013.
Creative Commons License

October 16, 2013

popHealth v2.4 Design for Meaningful Use Stage 2

As some of you know, I have been leading the open source popHealth project at MITRE for the past 4 years.  The MITRE popHealth team is currently working for the Veterans Health Administration (VHA).  Our work is focused on using popHealth as the software service allow the VHA to meet Meaningful Use Stage 2 certification for Clinical Quality Measures (CQMs).

Since we hadn't been working on popHealth in any substantial level in most of 2013, so we identified some problems for ongoing operations and maintenance (O&M) of the popHealth software when we started to put more and more engineers back on the project.  The concerns that the popHealth team had was the software that manages the User Interface (UI) presentation layer in the browser was becoming too complex and convoluted.  This had the potential for introducing difficulty when a non-MITRE contractor will eventually manage the popHealth software in an "O&M" mode for the VHA.  This will happen when our team completes the development task and moves off of this project.

What the popHealth team opted to do was to clean up the JavaScript and HTML so that there was an Application Programming Interface (API) that could provide JavaScript Object Notation (JSON) for the popHealth data needed for the UI directly to the browser.  This is a cleaner software design that also allows user to forgo the existing popHealth UI if they need to provide just the raw CQM data.

In the process of refactoring the popHealth web application infrastructure, the team opted to introduce some tweaks to the popHealth presentation layer but still maintain the existing interaction model.  What we decided to do was only slightly evolve the existing popHealth branding and look and feel, so that is is more maintainable from an engineers perspective, but does not introduce a radically different interaction model require re-training for all our existing users.

The popHealth v1.4 user interface that was aligned with the Meaningful Use Stage 2 program is below:

popHealth v1.4 Dashboard Design for Meaningful Use Stage 1

In the process of refactoring the popHealth web application infrastructure, the popHealth design team opted to introduce some tweaks to the presentation layer but still maintains the established L&F and interaction model.  The latest updated designs for popHealth v2.4 follow:

popHealth v2.4 Dashboard Design for Meaningful Use Stage 2

Changes in the evolved popHealth v2.4 design include:
  • Eliminated confusing links for the "parameters" of each CQM on the right; now, there is just a link to access the patients.
  • Reduced the number of colors and focused on a more muted and simplified color pallet 
  • Eliminated the single horizontal bar visualization and replaced it with two stacked bars for the fractions
  • Identified the exception and exclusion population with muted gray bars on the stacked bar charts
  • Enhanced the performance rate fraction with a visual radial circle around the fraction value
If anyone has opinions on the latest designs, the team welcomes any and all constructive feedback.

This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. © Rob McCready, 2013.
Creative Commons License

June 6, 2013

Thoughts on Clinical Quality Measure and Clinical Decision Support Convergence

I have been tracking several discussions for the past year to consider the convergence of Clinical
Quality Measures and Clinical Decision Support within Electronic Health Record systems.  As a quick refresher on the two types of healthcare reports:

Clinical Quality Measurement (CQM)

  • Typically post-event reporting on treatment, usually via a quarterly or annual basis
  • Longer term impact on healthcare quality of a population of patients


Clinical Decision Support (CDS)

  • Guide clinical choices during treatment now
  • More direct and immediate impact on the quality of care being provided to a patient

CQMs and CDS are clearly very closely related disciplines.  In fact, they are two sides of the same coin.  They both consider what actions providers take with the "hand they are dealt" with their patients.  For both types of reports, data in input via electronic clinical data, and both are implemented within EHR systems.  Additionally, the logic of a CDS rule and a CQM report are indeed very similar.

With CQMs, you are reviewing actions taken in the past to help educate and influence decisions in the future.

With CDS, you are working in real-time... in the present.

To put this in another context, with CQMs you may be viewing data that may have led to the death of a patient.  The goodness or badness has been performed by the provider or healthcare team.  With CDS, you have the potential to actually kill a patient by taking the wrong action.

This is the part of the CDS space that I personally find troubling to work with, since there is a much more real risk to harming a patient with either a bug in CDS logic or with ambiguity in standards that could be used to express CDS

Consider a Warfarin CQM that measures “Did you perform appropriate warfarin dosing?”  You could apply this CQM to a population of cardiac patients and consider the results in aggregate to see if over the course of a year.  Now consider a CDS that determines "What is the lethal dose of warfarin dosing that I am providing this patient... right now?!?”

For me, addressing the second scenario become really serious very quickly.  For healthcare providers, I do not think that they are phased with either domain, since they deal with life and death scenarios all the time.

But again, for me, these are the scenarios and domains where I lose sleep after work.

Several considerations have been discussed to expand the Health Quality Measures Format (HQMF) XML standard that is used for expressing the CQM logic for the Meaningful Use program.  The HQMF is an HL7 standard for representing a Clinical Quality Measure (CQMs) in XML.  The HQMF standard is a declarative approach to defining procedural CQM reporting logic.  What the HQMF standard has going for it, is (regrettably) being named the authoritative source for expressing the logic for the Meaningful Use Stage 2 CQMs.

The HQMF implementation of CQMs defines the data elements referenced by the logic, and associates them to value sets using object identifiers (OIDs).  These OIDs can then be used with the National Library of Medicine's (NLM's) Value Set Authority Center (VSAC) to translate clinical concepts into various operational clinical codes.

For those really interested in using the HQMF, you can download the HQMF files for all the Meaningful Use Stage 2 Clinical Quality Measures from the CMS site here.

Having worked with the HQMF XML standard indirectly for the past 2 years on both the popHealth project, and for the past year the Cypress project, my team has repeatedly expressed concern over the standard due to ambiguity and difficulty in ensuring that the HQMF standard is properly implemented in an EHR.  For our team, our challenge was consuming HQMF XML and turning it into procedural logic for Cypress and popHealth.

Based on the challenges my team has faced, I am very cautious about any considerations to re-use the HQMF standard for CDS support, since I feel it does a poor job expressing even the CQM logic.  My primary concern with the plans on converging CQMs and CDSs logic is the current declarative approach used for CQMs which is the HQMF XML standard.

What I feel is needed is a procedural definition of both CQM and CDS logic.  The reason for this need for procedural expression of the logic is that it allows for more rigorous testing, and also reduces the ambiguity associated with EHR systems have to implement their own parser to convert the declarative HQMF definition of either a CQM or CDS into their own procedural set of software instructions.

Consider the following procedural JavaScript logic built into popHealth v1.4 for the Meaningful Use Stage 1 CQM, NQF 0421 Adult Weight Screening:

function() {
  var patient = this;
  var measure = patient.measures["0421"];
  if (measure == null)
    measure={};

  var day = 24 * 60 * 60;
  var year = 365 * day;
  var effective_date = <%= effective_date %>;

  var measurement_period_start =  effective_date - (1 * year);
  var latest_birthdate = latestBirthdayForThisAge(65, measurement_period_start);
  var earliest_encounter =        measurement_period_start - year;

  var population = function() {
    var correct_age = patient.birthdate <= latest_birthdate;
    return (correct_age);
  }

  var denominator = function() {
    return inRange(measure.encounter_outpatient_encounter,
                   earliest_encounter, effective_date);
  }

  var numerator = function() {
    return weight_numerator(measure, 22, 30);
  }

  var exclusion = function() {
    return weight_exclusion(measure, earliest_encounter, effective_date);
  }

  map(patient, population, denominator, numerator, exclusion);
};

By having a single procedural definition for both CQMs and CDS, we should be able to have a higher level of confidence in the performance of the EHR systems that have to implement either a CQM or CDS.  What could then be done, is test and certify EHR systems ability to process the procedural definition of the standard, and then have a higher level of confidence that the any new CQM expressed in procedural logic... as long as it were syntactically well formed... would work with an EHR system.

The benefit to this type of approach is accelerated velocity in development, testing, and deployment of new CQMs and new CDS reports/rules.


This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. © Rob McCready, 2013.
Creative Commons License

May 17, 2013

Designing Logos for a Portfolio of Healthcare Projects

Over the past three years, I have been involved with numerous open source healthcare projects, ranging from large reference implementations of Clinical Quality Measures, certification and testing tools adopted by the federal government, a small research project assessing CQM complexity/cost/tractability, this blog, and other ideas that failed to launch.

What I have been endorsing throughout the course of the past three years has been to establish a common "brand" that could be applied to various open source healthcare projects, but still provide a unique look and feel for each individual project.  

The design approach that organically evolved was to develop logos followed the following rules:
  • Use only circles
  • The circles may come in different sizes and arrangements
  • Limiting the logos to a pallet of only two colors
  • Color opacity could be changed
You can see the portfolio of these project logos below:
Portfolio of logos for open source healthcare projects I have worked on
Portfolio of logos for open source healthcare projects I have worked on
Since I am a "left brain" engineer at heart, the various arrangements of the circles has been an easier task than color selection.  I have often struggled with finding the magic combination of colors for anything from these logos to our interior design of our hours.

The best resource that I have found been able to identify is ColorLovers.com.  For those not familiar with the site, it is an evolving resource for palettes and colors that users can share, rank and comment on.

When I had to select to colors, I went to the filter for "most loved" colors of all time, and tried to identify pallets where instead of 5 colors, there were 2 colors used in the pallet.  Hopefully this is a helpful trick.

This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. © Rob McCready, 2013.
Creative Commons License

May 6, 2013

Meaningful Use Stage 2 Exception vs. Exclusion Logic Explained

Introduced in Meaningful Use Stage 2 was the notion of both exception logic and exclusion logic with the Proportion-Based CQMs.  Based on numerous conversations over the past several months, there appears to be ongoing confusion in logical implementation of exception and exclusion logic for these CQMs as part of the Meaningful Use program.

The authoritative resource for this explanation is the Clinical Quality eMeasure Logic and Implementation Guidance Document that is publicly available on the CMS site.  The details for proportion-based CQM that I have paraphrased follows below:
  • Initial Patient Population: The set of patients (or episodes of care) to be evaluated by the measure.
  • Denominator Population: A subset of the Initial Patient Population.
  • Exclusion Population: The members of the Denominator that should not be considered for inclusion in the Numerator.
  • Numerator Population: A subset of the Denominator.  The numerator criteria are the processes or outcomes expected for each patient, procedure, or other unit of measurement defined in the denominator.
  • Exception Population: These are the members of the Denominator that were considered for membership in the Numerator, but were rejected, and meet the logic required for the exception criteria.
I have included an illustration that attempts to capture this updated logic for Meaningful Use Stage 2.

Meaningful Use Stage 2 Proportion-Based CQM Logic
Meaningful Use Stage 2 Proportion-Based CQM Logic

These final population counts are then used to calculate the performance rate of any CQM against a population of patients via the following formula:

Performance Rate = Numerator Count / (Denominator Count – Exclusion Count – Exception Count)


This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. © Rob McCready, 2013.
Creative Commons License

April 27, 2013

Example QRDA Category 1 XML for Meaningful Use Stage 2 Clinical Quality Measure Reporting

Last fall, I wrote about the QRDA Category 1 XML Standard as a way of expressing inputs to Clinical Quality Measures for the Meaningful Use Stage 2 program.  More recently, I have become immersed in the QRDA Category 1 while leading the open source Cypress project for the Office of the National Coordinator of Health Information Technology (ONC) and the Meaningful Use Stage 2 CQM Testing and Certification Program.

Under ONC, the Meaningful Use Program tests and certifies EHR technologies as part of the Meaningful Use Program via Authorized Testing Laboratories (ATLs), who are the organizations that use the tools and policies identified by ONC.  The Cypress project is the authoritative testing and certification tool used for the MU Stage 2 Clinical Quality Measures, and includes testing for the QRDA Category 1 XML specification.

Based on all the work our team has been supporting with the QRDA Category 1 XML, I thought it would be helpful to demonstrate how a CQM can define the data that would need to be expressed in a QRDA Category 1 XML file.

As an example, I am selecting NQF 0018 "Controlling High Blood Pressure", which measures the percentage of patients, aged 18-85 years old at the time of the CQM's measurement, and who had some sequence of encounters with a provider, and a diagnosis of hypertension, and whose blood pressure was adequately controlled (<140/90mmHg) during the measurement period.

If you wanted to see the full logic of this particular CQM, the visualization that is automatically generated from the open source popHealth project that I am leading is below:

Denominator Logic

birth date
>= 18 years starts before start of measure period
and
birth date
<= 85 years starts before start of measure period
and
essential hypertension
<= 6 months starts after start of measure period
or
essential hypertension
starts before start of measure period
and
office visit
during measure period
or
face-to-face interaction
during measure period
or
preventive care services - established office visit, 18 and up
during measure period
or
preventive care services-initial office visit, 18 and up
during measure period
or
home healthcare services
during measure period
or
annual wellness visit
during measure period

Numerator Logic

diastolic blood pressure < 90 mm Hg
duringrecent of
office visit
during measure period
or
outpatient consultation
during measure period
or
preventive care services-initial office visit, 18 and up
during measure period
or
preventive care services - established office visit, 18 and up
during measure period
or
face-to-face interaction
during measure period
or
home healthcare services
during measure period
or
annual wellness visit
during measure period
and
systolic blood pressure < 130 mm Hg
duringrecent of
office visit
during measure period
or
outpatient consultation
during measure period
or
preventive care services-initial office visit, 18 and up
during measure period
or
preventive care services - established office visit, 18 and up
during measure period
or
face-to-face interaction
during measure period
or
home healthcare services
during measure period
or
annual wellness visit
during measure period

Consider some realistic but minimal health data applied against that particular CQM and let's see what what a QRDA Category 1 XML file for me would look like.  Assume I have the following notional clinical data assigned to me in an Electronic Health Record system:

First Name: John
Last Name: Doe
DoB: June 24, 1975
Address: 123 Main Street Gardner, MA 01440
Work phone: 781-271-7102
HL7 Gender: Male
Spoken Language: English
CDC Race: White
CDC Ethnicity: Not Hispanic or Latino
Conditions: Hypertension diagnosed on March 1st, 2012
Encounters: Office Visit on March 1st, 2012
            Office Visit on July 1st, 2012
            Blood Pressure Visit on November 1st, 2012
Systolic BP: 127 mmHg on March 1st, 2012
             123 mmHg on November 1st, 2012
Diastolic BP: 79 mmHg on March 1st, 2012
              81 mmHg on November 1st, 2012

Now, lets see how that clinical data for this patient should be expressed in the (very verbose) QRDA Category 1 XML format.  As an FYI for how the QRDA Category 1 XML specification works, the data expressed in the QRDA Category 1 XML is in response to a CQM request.

Assume that the QRDA Category 1 XML below were generate for that particular CQM NQF 0018 "Controlling High Blood Pressure" for the Meaningful Use Stage 2 program.  Also, assume a reporting period ending on December 31st, 2012 23:59.  I am highlighting in yellow within the XML below where the clinical data that I enumerated for our notional patient is expressed in the QRDA Category 1 XML:




<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="cda.xsl"?>
<ClinicalDocument xmlns="urn:hl7-org:v3" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:voc="urn:hl7-org:v3/voc"
  xmlns:sdtc="urn:hl7-org:sdtc">
  <realmCode code="US"/>
  <typeId root="2.16.840.1.113883.1.3" extension="POCD_HD000040"/>
  <templateId root="2.16.840.1.113883.10.20.22.1.1"/>
  <templateId root="2.16.840.1.113883.10.20.24.1.1"/>
  <templateId root="2.16.840.1.113883.10.20.24.1.2"/>
  <id root="5b010313-eff2-432c-9909-6193d8416fac"/>
  <code code="55182-0"
   codeSystem="2.16.840.1.113883.6.1" 
   codeSystemName="LOINC" 
   displayName="Quality Measure Report"/>
  <title>QRDA Report for John Doe</title>
  <effectiveTime value="20130427145038"/>
  <confidentialityCode code="N"
    codeSystem="2.16.840.1.113883.5.25"/>
  <languageCode code="eng"/>
  <recordTarget>
    <patientRole>
      <id extension="12345" root="2.16.840.1.113883.4.572"/>
      <addr use="HP">
        <streetAddressLine>123 Main Street</streetAddressLine>
        <city>Gardner</city>
        <state>MA</state>
        <postalCode>01440</postalCode>
        <country>US</country>
      </addr>
      <telecom use="WP" value="tel:+1-781-271-7102"/>
      <patient>
        <name>
          <given>John</given>
          <family>Doe</family>
        </name>
        <administrativeGenderCode code="M" 
          codeSystem="2.16.840.1.113883.5.1" 
          codeSystemName="HL7 AdministrativeGender"/>
        <birthTime value="19750624120000"/>
        <raceCode code="2106-3"
          displayName="White" 
          codeSystemName="CDC Race and Ethnicity" 
          codeSystem="2.16.840.1.113883.6.238"/>
        <ethnicGroupCode code="2186-5" 
          displayName="Not Hispanic or Latino" 
          codeSystemName="CDC Race and Ethnicity" 
          codeSystem="2.16.840.1.113883.6.238"/>
        <languageCommunication>
          <templateId root="2.16.840.1.113883.3.88.11.83.2" 
            assigningAuthorityName="HITSP/C83"/>
          <templateId root="1.3.6.1.4.1.19376.1.5.3.1.2.1" 
            assigningAuthorityName="IHE/PCC"/>
          <languageCode code="eng"/>
        </languageCommunication>
      </patient>
    </patientRole>
  </recordTarget>
  <author>
    <time value="20130427145038"/>
    <assignedAuthor>
      <id extension="FakeNPI" root="2.16.840.1.113883.4.6"/>
      <addr>
        <streetAddressLine>234 Main Street</streetAddressLine>
        <city>Gardner</city>
        <state>MA</state>
        <postalCode>01440</postalCode>
        <country>US</country>
      </addr>
      <telecom use="WP" value="tel:(781)271-7102"/>
      <assignedAuthoringDevice>
        <manufacturerModelName>AcmeEHR</manufacturerModelName>
        <softwareName>AcmeEHR</softwareName>
      </assignedAuthoringDevice>
    </assignedAuthor>
  </author>
  <custodian>
    <assignedCustodian>
      <representedCustodianOrganization>
        <id root="2.16.840.1.113883.19.5"/>
        <name>Fake Custodian</name>
        <telecom use="WP" value="tel:(781)555-5555"/>
        <addr>
          <streetAddressLine>345 Main Street</streetAddressLine>
          <city>Gardner</city>
          <state>MA</state>
          <postalCode>01440</postalCode>
          <country>US</country>
        </addr>
      </representedCustodianOrganization>
    </assignedCustodian>
  </custodian>
  <legalAuthenticator>
    <time value="20130427145038"/>
    <signatureCode code="S"/>
    <assignedEntity>
      <id root="bc01a5d1-3a34-4286-82cc-43eb04c972a7"/>
      <addr>
        <streetAddressLine>567 Main Street</streetAddressLine>
        <city>Gardner</city>
        <state>MA</state>
        <postalCode>01440</postalCode>
        <country>US</country>
      </addr>
      <telecom use="WP" value="tel:(781)271-3000"/>
      <assignedPerson>
        <name>
          <given>Mike</given>
          <family>Doe</family>
        </name>
      </assignedPerson>
      <representedOrganization>
        <id root="2.16.840.1.113883.19.5"/>
        <name>AcmeEHR</name>
      </representedOrganization>
    </assignedEntity>
  </legalAuthenticator>
  <documentationOf typeCode="DOC">
    <serviceEvent classCode="PCPR">
      <effectiveTime>
        <low value="20100601"/>
        <high value="20100915"/>
      </effectiveTime>
      <performer typeCode="PRF">
        <time>
          <low value="20020716"/>
          <high value="20070915"/>
        </time>
        <assignedEntity>
          <id root="2.16.840.1.113883.4.6" extension="111111111"/>
          <representedOrganization>
            <id root="2.16.840.1.113883.4.2" extension="1234567"/>
            <id root="2.16.840.1.113883.4.336" extension="54321"/>
          </representedOrganization>
        </assignedEntity>
      </performer>
    </serviceEvent>
  </documentationOf>
  <component>
    <structuredBody>
      <component>
        <section>
          <templateId root="2.16.840.1.113883.10.20.24.2.2"/>
          <templateId root="2.16.840.1.113883.10.20.24.2.3"/>
          <code code="55186-1" codeSystem="2.16.840.1.113883.6.1"/>
          <title>Measure Section</title>
          <text>
            <table border="1" width="100%">
              <thead>
                <tr>
                  <th>eMeasure Title</th>
                  <th>Version neutral identifier</th>
                  <th>eMeasure Version Number</th>
                  <th>NQF eMeasure Number</th>
                  <th>Version specific identifier</th>
                </tr>
              </thead>
              <tbody>
                <tr>
                  <td>Controlling High Blood Pressure</td>
                  <td>ABDC37CC-BAC6-4156-9B91-D1BE2C8B7268</td>
                  <td>1</td>
                  <td>5177f5798538a2f952caf324</td>
                  <td>8A4D92B2-397A-48D2-0139-C6208B875109</td>
                  <td/>
                </tr>
              </tbody>
            </table>
          </text>
          <entry>
            <organizer classCode="CLUSTER" moodCode="EVN">
              <templateId root="2.16.840.1.113883.10.20.24.3.98"/>
              <!-- This is the templateId for eMeasure Reference QDM -->
              <templateId root="2.16.840.1.113883.10.20.24.3.97"/>
              <statusCode code="completed"/>
              <reference typeCode="REFR">
                <externalDocument classCode="DOC" moodCode="EVN">
                  <id root="8A4D92B2-397A-48D2-0139-C6208B875109"/>
                  <text>Controlling High Blood Pressure</text>
                  <setId root="ABDC37CC-BAC6-4156-9B91-D1BE2C8B7268"/>
                  <versionNumber value="1"/>
                </externalDocument>
              </reference>
            </organizer>
          </entry>
        </section>
      </component>
      <component>
        <section>
          <templateId root="2.16.840.1.113883.10.20.17.2.1"/>
          <code code="55187-9" codeSystem="2.16.840.1.113883.6.1"/>
          <title>Reporting Parameters</title>
          <text>
            <list>
              <item>Reporting period: January 1st, 2012 - 
                    December 31st, 2012</item>
            </list>
          </text>
          <entry typeCode="DRIV">
            <act classCode="ACT" moodCode="EVN">
              <templateId root="2.16.840.1.113883.10.20.17.3.8"/>
              <code code="252116004" 
                codeSystem="2.16.840.1.113883.6.96"
                displayName="Observation Parameters"/>
              <effectiveTime>
                <low value="20120101000000"/>
                <high value="20121231235900"/>
              </effectiveTime>
            </act>
          </entry>
        </section>
      </component>
      <component>
        <section>
          <templateId root="2.16.840.1.113883.10.20.17.2.4"/>
          <templateId root="2.16.840.1.113883.10.20.24.2.1"/>
          <code code="55188-7" codeSystem="2.16.840.1.113883.6.1"/>
          <title>Patient Data</title>
          <text/>
          <entry>
            <observation classCode="OBS" moodCode="EVN">
              <templateId root="2.16.840.1.113883.10.20.22.4.2"/>
              <templateId root="2.16.840.1.113883.10.20.24.3.57"/>
              <id root="1.3.6.1.4.1.115" extension="5177f5807938a7ce61000287"/>
              <code code="8462-4" 
                codeSystem="2.16.840.1.113883.6.1" 
                sdtc:valueSet="2.16.840.1.113883.3.526.3.1033">
                <originalText>Physical Exam, Finding:
                              Diastolic BP</originalText>
              </code>
              <statusCode code="completed"/>
              <effectiveTime>
                <low value="20120301120000"/>
                <high value="20120301120000"/>
              </effectiveTime>
              <value xsi:type="PQ" value="79" unit="mmHg"/>
            </observation>
          </entry>
          <entry>
            <observation classCode="OBS" moodCode="EVN">
              <templateId root="2.16.840.1.113883.10.20.22.4.2"/>
              <templateId root="2.16.840.1.113883.10.20.24.3.57"/>
              <id root="1.3.6.1.4.1.115" extension="5177f5807938a7ce6100028d"/>
              <code code="8462-4"
                codeSystem="2.16.840.1.113883.6.1"
                sdtc:valueSet="2.16.840.1.113883.3.526.3.1033">
                <originalText>Physical Exam, Finding:
                              Diastolic BP</originalText>
              </code>
              <statusCode code="completed"/>
              <effectiveTime>
                <low value="20121101120000"/>
                <high value="20121101120000"/>
              </effectiveTime>
              <value xsi:type="PQ" value="81" unit="mmHg"/>
            </observation>
          </entry>
          <entry>
            <encounter classCode="ENC" moodCode="EVN">
              <templateId root="2.16.840.1.113883.10.20.22.4.49"/>
              <templateId root="2.16.840.1.113883.10.20.24.3.23"/>
              <id root="1.3.6.1.4.1.115" extension="5177f5807938a7ce6100027f"/>
              <code code="99201"
                codeSystem="2.16.840.1.113883.6.12" 
               sdtc:valueSet="2.16.840.1.113883.3.464.1003.101.12.1001">
                <originalText>Encounter, Performed:
                              Office Visit</originalText>
              </code>
              <text>Encounter, Performed:
                    Office Visit</text>
              <statusCode code="completed"/>
              <effectiveTime>
                <low value="20120301120000"/>
                <high value="20120301130000"/>
              </effectiveTime>
            </encounter>
          </entry>
          <entry>
            <encounter classCode="ENC" moodCode="EVN">
              <templateId root="2.16.840.1.113883.10.20.22.4.49"/>
              <templateId root="2.16.840.1.113883.10.20.24.3.23"/>
              <id root="1.3.6.1.4.1.115" extension="5177f5807938a7ce61000280"/>
              <code code="99201"
                codeSystem="2.16.840.1.113883.6.12"
                   sdtc:valueSet="2.16.840.1.113883.3.464.1003.101.12.1001">
                <originalText>Encounter, Performed:
                              Office Visit</originalText>
              </code>
              <text>Encounter, Performed:
                    Office Visit</text>
              <statusCode code="completed"/>
              <effectiveTime>
                <low value="20120701120000"/>
                <high value="20120701130000"/>
              </effectiveTime>
            </encounter>
          </entry>
          <entry>
            <encounter classCode="ENC" moodCode="EVN">
              <templateId root="2.16.840.1.113883.10.20.22.4.49" />
              <templateId root="2.16.840.1.113883.10.20.24.3.23" />
              <id root="1.3.6.1.4.1.115" extension="5177f5807938a7ce61000281"/>
              <code code="185349003"
                codeSystem="2.16.840.1.113883.6.96"
                sdtc:valueSet="2.16.840.1.113883.3.464.1003.101.12.1001">
                <originalText>Encounter, Performed:
                              Blood Pressure Visit</originalText>
                <translation code="99202" codeSystem="2.16.840.1.113883.6.12"/>
              </code>
              <text>Encounter, Performed:
                    Blood Pressure Visit</text>
              <statusCode code="completed"/>
              <effectiveTime>
                <low value="20121101120000"/>
                <high value="20121101130000"/>
              </effectiveTime>
            </encounter>
          </entry>
          <entry>
            <encounter classCode="ENC" moodCode="EVN">
              <templateId root="2.16.840.1.113883.10.20.22.4.49" />
              <templateId root="2.16.840.1.113883.10.20.24.3.23" />
              <id root="1.3.6.1.4.1.115" extension="5177f5807938a7ce61000281" />
              <code code="185349003"
                codeSystem="2.16.840.1.113883.6.96"
              sdtc:valueSet="2.16.840.1.113883.3.464.1003.101.12.1048">
                <originalText>Encounter, Performed: 
                              Blood Pressure Visit</originalText>
                <translation code="99202"
                  codeSystem="2.16.840.1.113883.6.12"/>
              </code>
              <text>Encounter, Performed:
                    Blood Pressure Visit</text>
              <statusCode code="completed" />
              <effectiveTime>
                <low value="20121101120000" />
                <high value="20121101130000" />
              </effectiveTime>
            </encounter>
          </entry>
          <entry>
            <observation classCode="OBS" moodCode="EVN">
              <templateId root="2.16.840.1.113883.10.20.22.4.2" />
              <templateId root="2.16.840.1.113883.10.20.24.3.57" />
              <id root="1.3.6.1.4.1.115" extension="5177f5807938a7ce61000285" />
              <code code="8480-6" 
                codeSystem="2.16.840.1.113883.6.1" 
                sdtc:valueSet="2.16.840.1.113883.3.526.3.1032">
                <originalText>Physical Exam, Finding:
                              Systolic Blood Pressure</originalText>
              </code>
              <statusCode code="completed"/>
              <effectiveTime>
                <low value="20120301120500"/>
                <high value="20120301120500"/>
              </effectiveTime>
              <value xsi:type="PQ" value="127" unit="mmHg"/>
            </observation>
          </entry>
          <entry>
            <observation classCode="OBS" moodCode="EVN">
              <templateId root="2.16.840.1.113883.10.20.22.4.2" />
              <templateId root="2.16.840.1.113883.10.20.24.3.57" />
              <id root="1.3.6.1.4.1.115" extension="5177f5807938a7ce6100028b" />
              <code code="8480-6"
                codeSystem="2.16.840.1.113883.6.1"
                sdtc:valueSet="2.16.840.1.113883.3.526.3.1032">
                <originalText>Physical Exam, Finding:
                              Systolic Blood Pressure</originalText>
              </code>
              <statusCode code="completed"/>
              <effectiveTime>
                <low value="20121101120000"/>
                <high value="20121101120000"/>
              </effectiveTime>
              <value xsi:type="PQ" value="123" unit="mmHg"/>
            </observation>
          </entry>
          <entry>
            <observation classCode="OBS" moodCode="EVN">
              <templateId root="2.16.840.1.113883.10.20.22.4.4" />
              <templateId root="2.16.840.1.113883.10.20.24.3.11" />
              <id root="1.3.6.1.4.1.115" 
                extension="5177f5807938a7ce6100027e"/>
              <code code="282291009"
                displayName="diagnosis"
                codeSystem="2.16.840.1.113883.6.96"
                codeSystemName="SNOMED-CT"/>
              <text>Diagnosis, Active: Hypertension</text>
              <statusCode code="completed"/>
              <effectiveTime>
                <low value="20120301123000"/>
                <high nullFlavor="UNK"/>
              </effectiveTime>
              <value code="10725009" 
                codeSystem="2.16.840.1.113883.6.96" 
                xsi:type="CD"
                sdtc:valueSet="2.16.840.1.113883.3.464.1003.104.12.1011">
                <originalText>Diagnosis, Active: Hypertension</originalText>
                <translation code="401.1"
                  codeSystem="2.16.840.1.113883.6.103"/>
              </value>
              <entryRelationship typeCode="REFR">
                <observation classCode="OBS" moodCode="EVN">
                  <templateId root="2.16.840.1.113883.10.20.22.4.6"/>
                  <templateId root="2.16.840.1.113883.10.20.24.3.94"/>
                  <id root="da6b50c0-9177-0130-01b7-12313d02bdec" />
                  <code code="33999-4" 
                    codeSystem="2.16.840.1.113883.6.1" 
                    codeSystemName="LOINC" displayName="status" />
                  <statusCode code="completed"/>
                  <value xsi:type="CD"
                    code="55561003"
                    displayName="active"
                    codeSystem="2.16.840.1.113883.6.96"
                    codeSystemName="SNOMED CT"/>
                </observation>
              </entryRelationship>
            </observation>
          </entry>
        </section>
      </component>
    </structuredBody>
  </component>
</ClinicalDocument>

If your first impression that this is bloated XML... you are not alone.

The primary cause of this "bloat" really traces its routes back to the HL7 Clinical Document Architecture and the HL7 RIM for expressing effectively anything (from individual patient records to Clinical Quality Measure procedural logic!) in XML.  However, as much as I hate HL7 XML-based documents, there is a little bit of goodness with respect to the QRDA Category 1 XML for expressing patient-level data as inputs to Clinical Quality Measures.

Several HL7 standards have proven to demonstrate failures as inputs to Clinical Quality Measures; the HL7 Continuity of Care Document (CCD), the HITSP C32, or the Consolidated CDA.  These are all general XML standards meant for expressing patient-level data for continuity of care from one provider to another via an XML format.

The silver lining on the QRDA Category 1 cloud is that once the clinical data that is needed for a particular CQM has been identified in an EHR system, the way to express that clinical data on a patient-by-patient basis is clear(er) and more tractable for systems that will need to parse and interoperate with the structured data.

This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. © Rob McCready, 2013.
Creative Commons License