COVID-19 Diagnostic Test in FHIR format - hl7-fhir

I not really familiar with FHIR data format and need some help here. The story is, all the registered labs will sent the patient COVID-19 Diagnostic Test in our database. So the information they provide is
Basic patient information
Lab information (Lab name, contact and address) where the user take the test
Type of test (RNA, PCR, Antigen, or Antibody test)
Result of test (Positive or Negative)
I looking to follow this format from HERE. But I not sure which LOINC code I should use, and how to tell the result positive or negative.
{
"resourceType": "ValueSet",
"id": "Covid19Labs",
"text": {
"status": "generated",
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><p>This value set includes codes based on the following rules:</p><ul><li>Import all the codes that are contained in http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1032.109</li><li>Include these codes as defined in <code>http://loinc.org</code><table class=\"none\"><tr><td style=\"white-space:nowrap\"><b>Code</b></td><td><b>Display</b></td></tr><tr><td>94307-6</td><td>SARS-CoV-2 (COVID-19) N gene [Presence] in Unspecified specimen by Nucleic acid amplification using CDC primer-probe set N1</td></tr><tr><td>94308-4</td><td>SARS-CoV-2 (COVID-19) N gene [Presence] in Unspecified specimen by Nucleic acid amplification using CDC primer-probe set N2</td></tr><tr><td>94309-2</td><td>SARS-CoV-2 (COVID-19) RNA [Presence] in Unspecified specimen by NAA with probe detection</td></tr><tr><td>94310-0</td><td>SARS-like coronavirus N gene [Presence] in Unspecified specimen by NAA with probe detection</td></tr><tr><td>94314-2</td><td>SARS-CoV-2 (COVID-19) RdRp gene [Presence] in Unspecified specimen by NAA with probe detection</td></tr><tr><td>94315-9</td><td>SARS-related coronavirus E gene [Presence] in Unspecified specimen by NAA with probe detection</td></tr><tr><td>94316-7</td><td>SARS-CoV-2 (COVID-19) N gene [Presence] in Unspecified specimen by NAA with probe detection</td></tr><tr><td>94500-6</td><td>SARS-CoV-2 (COVID-19) RNA [Presence] in Respiratory specimen by NAA with probe detection</td></tr><tr><td>94533-7</td><td>SARS-CoV-2 (COVID-19) N gene [Presence] in Respiratory specimen by NAA with probe detection</td></tr><tr><td>94534-5</td><td>SARS-CoV-2 (COVID-19) RdRp gene [Presence] in Respiratory specimen by NAA with probe detection</td></tr><tr><td>94559-2</td><td>SARS-CoV-2 (COVID-19) ORF1ab region [Presence] in Respiratory specimen by NAA with probe detection</td></tr><tr><td>94759-8</td><td>SARS-CoV-2 (COVID-19) RNA [Presence] in Nasopharynx by NAA with probe detection</td></tr><tr><td>94558-4</td><td>SARS-CoV-2 (COVID-19) Ag [Presence] in Respiratory specimen by Rapid immunoassay</td></tr></table></li></ul></div>"
},
"url": "http://hl7.org/fhir/uv/saner/ValueSet/Covid19Labs",
"version": "0.1.0",
"name": "Covid19Labs",
"title": "COVID-19 Diagnostic Test",
"status": "active",
"date": "2021-06-09T20:53:59+00:00",
"publisher": "HL7 International Public Health Workgroup",
"contact": [
{
"telecom": [
{
"system": "url",
"value": "http://hl7.org/Special/committees/pher/index.cfm"
}
]
},
{
"telecom": [
{
"system": "email",
"value": "pher#lists.hl7.org"
}
]
},
{
"name": "HL7 Public Health Workgroup",
"telecom": [
{
"system": "url",
"value": "http://hl7.org/Special/committees/pher/index.cfm"
}
]
},
{
"name": "Keith W. Boone",
"telecom": [
{
"system": "email",
"value": "mailto:kboone#ainq.com"
}
]
}
],
"description": "Codes for COVID-19 Diagnostic Tests",
"jurisdiction": [
{
"coding": [
{
"system": "http://unstats.un.org/unsd/methods/m49/m49.htm",
"code": "001"
}
]
}
],
"copyright": "This material contains content from LOINC (http://loinc.org). LOINC is copyright © 1995-2020, Regenstrief Institute, Inc. and the Logical Observation Identifiers Names and Codes (LOINC) Committee and is available at no cost under the license at LOINC/license. LOINC® is a registered United States trademark of Regenstrief Institute, Inc",
"compose": {
"include": [
{
"valueSet": [
"http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1032.109"
]
},
{
"system": "http://loinc.org",
"concept": [
{
"code": "94307-6",
"display": "SARS-CoV-2 (COVID-19) N gene [Presence] in Unspecified specimen by Nucleic acid amplification using CDC primer-probe set N1"
},
{
"code": "94308-4",
"display": "SARS-CoV-2 (COVID-19) N gene [Presence] in Unspecified specimen by Nucleic acid amplification using CDC primer-probe set N2"
},
{
"code": "94309-2",
"display": "SARS-CoV-2 (COVID-19) RNA [Presence] in Unspecified specimen by NAA with probe detection"
},
{
"code": "94310-0",
"display": "SARS-like coronavirus N gene [Presence] in Unspecified specimen by NAA with probe detection"
},
{
"code": "94314-2",
"display": "SARS-CoV-2 (COVID-19) RdRp gene [Presence] in Unspecified specimen by NAA with probe detection"
},
{
"code": "94315-9",
"display": "SARS-related coronavirus E gene [Presence] in Unspecified specimen by NAA with probe detection"
},
{
"code": "94316-7",
"display": "SARS-CoV-2 (COVID-19) N gene [Presence] in Unspecified specimen by NAA with probe detection"
},
{
"code": "94500-6",
"display": "SARS-CoV-2 (COVID-19) RNA [Presence] in Respiratory specimen by NAA with probe detection"
},
{
"code": "94533-7",
"display": "SARS-CoV-2 (COVID-19) N gene [Presence] in Respiratory specimen by NAA with probe detection"
},
{
"code": "94534-5",
"display": "SARS-CoV-2 (COVID-19) RdRp gene [Presence] in Respiratory specimen by NAA with probe detection"
},
{
"code": "94559-2",
"display": "SARS-CoV-2 (COVID-19) ORF1ab region [Presence] in Respiratory specimen by NAA with probe detection"
},
{
"code": "94759-8",
"display": "SARS-CoV-2 (COVID-19) RNA [Presence] in Nasopharynx by NAA with probe detection"
},
{
"code": "94558-4",
"display": "SARS-CoV-2 (COVID-19) Ag [Presence] in Respiratory specimen by Rapid immunoassay"
}
]
}
]
}
}
Any idea how to do it? Thanks in advance

Azri,
Here's an example of what an instance of an Observation would look like for a SARS CoV 2 (the causative agent of COVID-19) lab test.
{
"resourceType" : "Observation",
"id" : "SARS_CoV2_example",
"meta" : {
"extension" : [
{
"url" : "http://hl7.org/fhir/StructureDefinition/instance-name",
"valueString" : "COVID-Example"
},
{
"url" : "http://hl7.org/fhir/StructureDefinition/instance-description",
"valueMarkdown" : "This is an example of a lab test for SARS CoV 2."
}
],
"versionId" : "1",
"lastUpdated" : "2021-06-22T15:29:57.818+00:00",
"profile" : [
"http://fhir.logicahealth.org/covid19/StructureDefinition/SARScoronavirus2AbIgGPlusIgMPrThrPtSerPlasOrdIALabObs"
]
},
"status" : "final",
"category" : [
{
"coding" : [
{
"system" : "http://terminology.hl7.org/CodeSystem/observation-
category",
"code" : "laboratory",
"display" : "Laboratory"
}
],
"text" : "Laboratory"
}
],
"code" : {
"coding" : [
{
"system" : "http://loinc.org",
"code" : "94547-7",
"display" : "SARS-CoV-2 (COVID-19) IgG+IgM Ab [Presence] in Serum or Plasma
by Immunoassay"
}
],
"text" : "SARS-CoV-2 (COVID-19) IgG+IgM Ab [Presence] in Serum or Plasma by
Immunoassay"
},
"subject" : {
"reference" : "Patient/1234",
},
"effectiveDateTime" : "2021-06-05",
"performer": "Organization/123",
"valueCodeableConcept" : {
"system" : "http://snomed.info/sct",
"value" : "10828004",
"display": "Positive (qualifier value)"
}
}
The patient information is a reference to an instance of the Patient resource. For this example it may look like:
{
"resourceType": "Patient",
"id": "1234",
"lastUpdated": "2021-06-22T15:29:57.818+00:00",
"identifier": [
{
"system": "http://example_hopsital.org/EHR",
"value": "143762_XYZ"
}
],
"name": [
{
"given": "example",
"family": "Patient"
}
],
"birthDate": "2003-02-14"
}
Likewise, the lab information is a reference to an instance of the Organization resource that may look like:
{
"resourceType": "Organization",
"id": "123",
"lastUpdated": "2021-06-22T15:29:57.818+00:00",
"identifier": [
{
"system": "http://HopsitalX.org/LIS",
"value": "543XCB_HospitalLab",
}
],
"name": "HospitalX-Lab"
}
The type of test (PCR, RNA, antibody, etc.) is defined by the LOINC code in the Observation.code element.
The code snippet you placed in your question is an instance of the ValueSet resource and defines a set of LOINC codes created for SARS CoV 2 testing. It's used as both a knowledge resource (helps you know what LOINC codes are for SARS CoV 2) and a validation tool (helps you determine if an Observation instance is one of the SARS CoV 2 LOINC tests).

Related

FHIR to OMOP Mapping Question: Blood pressure systolic and diastolic with unmapped, not valid code (55284-4)

There is a LOINC concept 55284-4 that appears in some FHIR resources, for example:
https://syntheticmass.mitre.org/v1/fhir/Patient/0000aa42-c235-4447-8389-8a2640f44466/$everything
This code is for "Blood pressure systolic and diastolic" and is in the OMOP concept table as shown below.
This concept is not a standard concept, is not a valid concept (from OMOP's perspective) and does not have a mapping to any standard concept in OMOP.
This concept appears in the FHIR resource in the snippet shown below (from the synthmass url shown above).
What records should be created in OMOP to represent the snippet shown below?
"resource": {
"category": [
{
"coding": [
{
"code": "vital-signs",
"display": "vital-signs",
"system": http://hl7.org/fhir/observation-category
}
]
}
],
"code": {
"coding": [
{
"code": "55284-4",
"display": "Blood Pressure",
"system": http://loinc.org
}
],
"text": "Blood Pressure"
},
"component": [
{
"code": {
"coding": [
{
"code": "8462-4",
"display": "Diastolic Blood Pressure",
"system": http://loinc.org
}
],
"text": "Diastolic Blood Pressure"
},
"valueQuantity": {
"code": "mmHg",
"system": http://unitsofmeasure.org,
"unit": "mmHg",
"value": 84.88290301982099
}
},
{
"code": {
"coding": [
{
"code": "8480-6",
"display": "Systolic Blood Pressure",
"system": http://loinc.org
}
],
"text": "Systolic Blood Pressure"
},
"valueQuantity": {
"code": "mmHg",
"system": http://unitsofmeasure.org,
"unit": "mmHg",
"value": 117.69213707496547
}
}
],
"context": {
"reference": "Encounter/52430cb1-a0d3-4d1e-926c-c878c218502e"
},
"effectiveDateTime": "2018-05-06T04:07:24-04:00",
"id": "186e8672-f9ac-4419-8c5d-1e824bf6e536",
"issued": "2018-05-06T04:07:24.278-04:00",
"meta": {
"lastUpdated": "2019-04-09T08:36:08.363897+00:00",
"versionId": "MTU1NDc5ODk2ODM2Mzg5NzAwMA"
},
"resourceType": "Observation",
"status": "final",
"subject": {
"reference": "Patient/0000aa42-c235-4447-8389-8a2640f44466"
}
}
EDIT: ADDITIONAL INFORMATION
It looks like these are probably commonly used concepts for blood pressure in OMOP
select
*
from
concept
where 1=1
and (
lower(concept_name) = 'systolic blood pressure' or
lower(concept_name) = 'diastolic blood pressure')
and domain_id = 'Measurement'
and standard_concept = 'S';
And there are lots of other potential candidates (about 380 of them):
select
*
from
concept
where 1=1
and lower(concept_name) like '%blood pressure%'
and domain_id = 'Measurement'
and standard_concept = 'S';
I would map it the same as if it was LOINC code 85354-9. However, you should file an issue with Synthea because using the code 55284-4 without also having a translation of 85354-9 is non-conformant. (All FHIR conformant systems conveying a combined 'blood pressure' Observation are required to adhere to this profile, which mandates the 85354-9 code.)

Gaussian constraint in `normfactor`

I would like to understand how to impose a gaussian constraint with central value expected_yield and error expected_y_error on a normfactor modifier. I want to fit observed_data with a single sample MC_derived_sample. My goal is to extract the bu_y modifier such that the integral of MC_derived_sample scaled by bu_y is gaussian-constrained to expected_yield +/- expected_y_error.
My present attempt employs the normsys modifier as follows:
spec = {
"channels": [
{
"name": "singlechannel",
"samples": [
{
"name": "constrained_template",
"data": MC_derived_sample*expected_yield, #expect normalisation around 1
"modifiers": [
{"name": "bu_y", "type": "normfactor", "data": None },
{"name": "bu_y_constr", "type": "normsys",
"data":
{"lo" : 1 - (expected_y_error/expected_yield),
"hi" : 1 + (expected_y_error/expected_yield)}
},
]
},
]
},
],
"observations": [
{
"name": "singlechannel",
"data": observed_data,
}
],
"measurements": [
{
"name": "sig_y_extraction",
"config": {
"poi": "bu_y",
"parameters": [
{"name":"bu_y", "bounds": [[(1 - (5*expected_y_error/expected_yield), 1+(5*expected_y_error/expected_yield)]], "inits":[1.]},
]
}
}
],
"version": "1.0.0"
}
My thinking is that normsys will introduce a gaussian constraint about unity on the sample scaled by expected_yield.
Please can you provide me any feedback as to whether this approach is correct, please?
In addition, suppose I wanted to include a staterror modifier for the Barlow-Beeston lite implementation, would this be the correct way of doing so?
"samples": [
{
"name": "constrained_template",
"data": MC_derived_sample*expected_yield, #expect normalisation around 1
"modifiers": [
{"name": "BB_lite_uncty", "type": "staterror", "data": np.sqrt(MC_derived_sample)*expected_yield }, #assume poisson error and scale by central value of constraint
{"name": "bu_y", "type": "normfactor", "data": None },
{"name": "bu_y_constr", "type": "normsys",
"data":
{"lo" : 1 - (expected_y_error/expected_yield),
"hi" : 1 + (expected_y_error/expected_yield)}
},
]
}
Thanks a lot in advance for your help,
Blaise

Creating Observation FHIR Json using hourly data

I have a data in the following format csv format
where HR is heart rate, O2Sat is Oxygen Saturation, Temp is temperaute, ICULOS as ICU Length of Stay(showing hour number ranges from 1 to 100).
Now, i am trying to convert this to FHIR format. Since All these things come under observation, i am creating an observation template. For each column i am able to find a sample json where i can feed in the value.
I am not really sure how to interpret hourly data in FHIR. EffectiveTime, EffectivePeriod keys are not taking integer values and eventually failing in FHIR validation.
{
"resourceType": "Observation",
"id": "heart-rate",
"meta": {
"profile": [
"http://hl7.org/fhir/StructureDefinition/vitalsigns"
]
},
"status": "registered",
"category": [
{
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/observation-category",
"code": "vital-signs",
"display": "Vital Signs"
}
],
"text": "Vital Signs"
}
],
"code": {
"coding": [
{
"system": "http://loinc.org",
"code": "8867-4",
"display": "Heart rate"
}
],
"text": "Heart rate"
},
"subject": {
"reference": "Patient/example"
},
"effectiveDateTime": "1999-07-02",
"valueQuantity": {
"value": 0,
"unit": "beats/minute",
"system": "http://unitsofmeasure.org",
"code": "/min"
}
}
Can someone help me with the format to include hourly data and also how the json would be nested with multiple columns present in the figure ?
NOTE: ICULOS - has entry upto 100 hours.. For each hour values are denoted.
You would have a separate Observation for each measurement for each hour (with an appropirate effectiveDateTime indicating the specific time of each measurement). For example, you might have an effectiveDateTime of "1999-07-02T03:57:15" for the first and "1999-07-02T05:01:22" for the next. If you have no clue what time the measurements were made at and just have an hourly list, then simply go with "1999-07-02T00:00:00", "1999-07-02T01:00:00", etc.

Inserting multiple observation values in single resource - FHIR

I have hourly information for the patients heart rate like this
PID Hour HR
1 1 97
1 2 89
1 3 90
1 4 100
.....
.....
1 100 93
for each hour data i created json like this
# For Hour 1
{
"resourceType": "Observation",
"id": "heart-rate",
"meta": {
"profile": [
"http://hl7.org/fhir/StructureDefinition/vitalsigns"
]
},
"status": "final",
"category": [
{
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/observation-category",
"code": "vital-signs",
"display": "Vital Signs"
}
],
"text": "Vital Signs"
}
],
"code": {
"coding": [
{
"system": "http://loinc.org",
"code": "8867-4",
"display": "Heart rate"
}
],
"text": "Heart rate"
},
"subject": {
"reference": "Patient/example"
},
"effectiveDateTime": "2020-04-21T00:00:00+05:30",
"valueQuantity": {
"value": 97,
"unit": "beats/minute",
"system": "http://unitsofmeasure.org",
"code": "/min"
}
}
# Hour 2
{
"resourceType": "Observation",
"id": "heart-rate",
"meta": {
"profile": [
"http://hl7.org/fhir/StructureDefinition/vitalsigns"
]
},
"status": "final",
"category": [
{
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/observation-category",
"code": "vital-signs",
"display": "Vital Signs"
}
],
"text": "Vital Signs"
}
],
"code": {
"coding": [
{
"system": "http://loinc.org",
"code": "8867-4",
"display": "Heart rate"
}
],
"text": "Heart rate"
},
"subject": {
"reference": "Patient/example"
},
"effectiveDateTime": "2020-04-21T01:00:00+05:30",
"valueQuantity": {
"value": 89,
"unit": "beats/minute",
"system": "http://unitsofmeasure.org",
"code": "/min"
}
}
I created a resource bundle with 100 jsons nested inside entry and i am able to push it inside fhir-server.
{"resourceType": "Bundle", "type": "batch", "entry": [
The example given above is for one patient and one observation resource (heart-rate). I have more than 20000 patients with 50 different observation resource types.
Instead of creating 100 different json entries , is there any way to have one json representing 100 values. in value quantity if there is any way to have array of values mapped with timestamp. It would save lot of time.
For a single observation type and a single subject, if the observations are being made on a regular periodic basis, you can use the SampledData data type as the Observation.value. Typically that's for things like EKGs, fetal heart rate monitors, etc. which are sampling on a frequent basis, but nothing stops you from having a sampling period of an hour. However, if you don't have regular sampling, you must capture each as a distinct Observation. The reason is that we need to be able to extract the data however the user chooses to query it. The data needs to come in with the same sort of fine-grained organization that it might later need to go out. You might look at the Bulk Data API which uses LD-JSON to allow more efficient processing of large volumes of data.

ElasticSearch: Nested fields and aggregation

I see a few posts around nested fields and aggregation, but none of them seem to answer my question. So, pardon me if this is a repeated question and any help would be greatly appreciated.
We've built an index of lectures, and lectures have the following qualities:
A lecture can either be in-person (live) or pre-recorded (online)
Each lecture can have multiple chapters
Each of these chapters can be covered by different lecturers (example: chapter 1 of quantum physics can be covered by five different lecturers, and three of them may be live and the other two may be online)
An online lecture will always have one entry per lecturer per chapter per quality
Roughly the structure is as follows:
{
"topics": [
{
"id": "TOP1",
"chapters": [
{
"chapterId": 12345,
"availability": [
{
"type": "LIVE",
"lecturer": "Dr. Abraham Fisher",
"lectureChapterId": "861731",
"availableFrom": "2017-09-11 13:00:00",
"expiresAt": "2017-09-11 15:00:00",
"lecturerIds": [
"MON121",
"MEL122"
]
},
{
"type": "LIVE",
"lecturer": "Dr. Bob Fisher",
"lectureChapterId": "181751",
"availableFrom": "2017-09-11 20:00:00",
"expiresAt": "2017-09-11 22:00:00",
"lecturerIds": [
"MON122",
"MEL123"
]
},
{
"type": "LIVE",
"lecturer": "Dr. Bob Fisher",
"lectureChapterId": "181751",
"availableFrom": "2017-09-17 20:00:00",
"expiresAt": "2017-09-17 22:00:00",
"lecturerIds": [
"MON122",
"MEL123"
]
},
{
"type": "LIVE",
"lecturer": "Dr. Abraham Fisher",
"lectureChapterId": "861731",
"availableFrom": "2017-09-17 13:00:00",
"expiresAt": "2017-09-17 15:00:00",
"lecturerIds": [
"MON121",
"MEL122"
]
},
{
"type": "ONLINE",
"quality" : "HD",
"price" : 19.99,
"lecturer": "Dr. Catherine Fisher",
"lectureChapterId": "9127312",
"availableFrom": "2017-01-17 00:00:00",
"expiresAt": "2017-12-31 23:59:59",
"lecturerIds": [
"MON120",
"MEL120"
]
},
{
"type": "ONLINE",
"quality" : "SD",
"price" : 10.99,
"lecturer": "Dr. Catherine Fisher",
"lectureChapterId": "9127312",
"availableFrom": "2017-01-17 00:00:00",
"expiresAt": "2017-12-31 23:59:59",
"lecturerIds": [
"MON120",
"MEL120"
]
}
]
}
]
}
]
}
Now if the requirement is to return only the details first available lecture grouped by chapter, lecturer for LIVE lectures and return all online lectures (along with other metadata for the lecture topic), what is the best way to do that? In the example above, lectures by Dr. Abraham Fisher and Dr. Bob Fisher on the 11th of September should be returned.
I tried using inner_hits, but apparently, it doesn't allow aggregations (I get the following error).
"[nested] query does not support [aggs]"
P.S: The aggregation needs to be at a chapter level and not at the lecture topic (root) level.
Can you post your query? For an aggregation of a nested field, you always need to specify the nested path. See https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-nested-aggregation.html
I do not know your full data model, but if you have control over the document structure and you only need it for search, you could try to flatten it a bit more by denormalization.

Resources