Diagnostic reports vs legacy ways to persist lab test results

Hi @ibacher,

My understanding is that diagnostic reports are used to model lab test results. If correct this is definitely what we intend to use to save the results from the LIMS back into OpenMRS (in the context of our LIMS integration.)

However the question is: how much does this remain backward compatible with existing practices out there? The one that comes to mind directly is Bahmni, since Bahmni processes lab test results from OpenELIS.

Bahmni for instance saves an obs group whose top level obs is defined with the test order’s concept (see here and here).

Wondering how others have been saving lab test results historically, @ball what about you guys at PIH?

Cc @mksrom @ruhanga

1 Like

@mksd Not sure about Diagnostic reports.

PIH continues to use a lab test results htmlform with obs for back entry of data, while we also use our newest lab workflow functionality for point-of-care orders/results. It’s not clean, but it’s working.

The FHIR DiagnosticReport resource doesn’t itself contain any lab results. It’s more of a metadata wrapper for lab results, something closer to the form containing the lab results with header information about the lab, the performer, etc. The lab results themselves are modelled in both FHIR and our implementation as Observations. Observations are linked to a DiagnosticReport via that DiagnosticReport.result field in FHIR, which just represents a reference to the underlying Observation.

Initially, our implementation of DiagnosticReport looked quite a bit like Bahmni’s implementation, i.e., with an ObsGroup with a top-level Obs. We ran into some issues with this around being able to keep stable identifiers for the DiagnosticReport if it’s stored as an Obs group and, in any case, it didn’t seem very backwards compatible, so in the 1.0.0 release, DiagnosticReport is it’s own table (fhir_diagnostic_report) with links to the obs that constitute the DiagnosticReport (stored in the fhir_diagnostic_report_results table). This means that, generally speaking, DiagnosticReport resource won’t exist unless they’re explicitly created, but I don’t really see a great way around that as a generic solution.

One thing that hasn’t been highlighted enough is that the FHIR2 module is, by design, overrideable using code and the Spring configuration so that, i.e., it would be possible to write an implementation of DiagnosticReport that adheres to Bahmni’s model or to other implementation’s needs.

For the most part, I anticipate that the DiagnosticReport resource is mostly of value to people using FHIR to send and receive lab results rather than for historical data (which remains stored as Obs and queryable as FHIR Observations).

1 Like

@ibacher so typically each obs-result of the diagnostic report could be the top-level obs of a group such as the one used in Bahmni?

Yes, they definitely could be!

I think the approach we’ve adopted now aligns with the approach @angshuonline said was his preferred approach the last time I spoke with him about what DiagnosticReports should look like.

If a UI app fetches FHIR diagnostic reports as a mean to access lab results, it will be up to that app to know how to interpret the results right?

I guess it is reasonable to assume that a single lab result will be modelled as an obs group, since multiple pieces of answer make the entire result. From that point, the question is how do those obs group differ out there?

For instance, how does your obs group differ from Bahmni’s? By your obs group I mean the one that you may have used in the context of the OpenELIS Global integration.

So, just to be clear, we’re no longer using an Obs group. But previously, the top-level Obs held the code for the test / panel performed and then the Obs members were the actual results. I’m not exactly sure how that relates to the Bahmni implementation (I haven’t had time to look into the detail yet).

So, hopefully, the front-end app shouldn’t have to have too much logic. I.e., the data returned in DiagnosticReport.results should be actual result observations, although I suppose it’s possible that those could themselves be ObsGroups (Observations in FHIR can include other Observations via the hasMember property).

That said, I’m not sure that a DiagnosticReport is fundamentally the right resource for, say, a lab results display, since, as I understand things, from a clinical perspective, one primarily cares about the actual result rather than the provenance of the result, so you’d ideally want to do something like this to get all lab results for a patient:

GET /Observation?patient.identifier=[id]&category=laboratory&_sort=-date

Or for a specific type of lab result (CD4, for instance):

GET [base]/Observation?patient.identifier=[id]&code=http%3A%2F%2Floinc.org%7C20605-2&_count=3&_sort=-date

Basically, I’m not sure there’s a strong use-case for using things other than raw observations.

Thanks @ibacher. I guess we will stick to observations indeed, most likely in a Bahmni-friendly fashion for now.

But so you did not use any obs group in the end, you just made all the “members” to be the results of the diagnostic report?

In your case each result is in fact a piece of the overall lab test result, wrapped inside the diagnostic report (thereby providing some more metadata)?

Yes. That seemed to be the way of modelling observations that was most similar to how HTMLFormEntry is usually used. That was kind of the inspiration for it.

The dilemma is thus single wrapper vs double wrapper.

  • Single wrapper: what you did.
  • Double wrapper: diagnostic report with one obs group result to stick to “the Bahmni way”.
1 Like

I’m going to need some time to look more closely at what Bahmni does to have a coherent recommendation here.