Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add minimum provenance to FHIR converter for data source #755

Merged
merged 19 commits into from
Aug 2, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
b31ea86
added two functions for minimum provenance
Jul 31, 2023
48fae20
added test for first of the SDK functions
Aug 1, 2023
6141092
fixed the SDK function to make it generic; data_source is supplied
robertmitchellv Aug 1, 2023
58e0de1
removed test for function we're not using; added test for refactored …
robertmitchellv Aug 1, 2023
27c5aed
forgot to run black
robertmitchellv Aug 1, 2023
b2ac5a0
ensured that there was a 'meta' for every resource; test passes locally
robertmitchellv Aug 1, 2023
e23bb1c
added another test to make sure ValueError is raised and to bump up c…
robertmitchellv Aug 1, 2023
f4a6d97
Merge branch 'main' into robert/add-data-source-to-bundle
robertmitchellv Aug 1, 2023
dffa872
removed the functions and tests from SDK
robertmitchellv Aug 2, 2023
060d181
added function and test to the fhir-converter script--it hasn't been …
robertmitchellv Aug 2, 2023
b96b29b
removed old import from utils, added import to container tests and te…
robertmitchellv Aug 2, 2023
56fed1e
removed pathlib depend and added minimal test bundle
robertmitchellv Aug 2, 2023
4d1fcfa
added pytest to test imports
robertmitchellv Aug 2, 2023
d9d015c
added function to the fhir converter function using input_type as source
robertmitchellv Aug 2, 2023
2048d65
realized there was already a valid bundle; removed the one i added
robertmitchellv Aug 2, 2023
eddeef6
removed unneeded test data
robertmitchellv Aug 2, 2023
5085229
added logic to test provenance in the fhir converter
robertmitchellv Aug 2, 2023
d056aa3
added test for provenance to the valid fhir converter test; passes lo…
robertmitchellv Aug 2, 2023
7330c0f
typo
Aug 2, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions phdi/fhir/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,71 @@ def get_one_line_address(address: dict) -> str:
if address.get("postalCode", ""):
raw_one_line += f" {address['postalCode']}"
return raw_one_line


def is_response_fhirresource(bundle: dict) -> bool:
"""
Check if the FHIR bundle being passed as an argument is a
response.FhirResource and that its status is "200 OK".

:param bundle: The FHIR bundle to check for status "200 OK"
and that it is a response.FhirResource.
:return: A boolean indicating if the FHIR bundle is a
response.FhirResource (True) or not (False).
"""
if (
"response" in bundle
and "status" in bundle["response"]
and bundle["response"]["status"] == "200 OK"
and "FhirResource" in bundle["response"]
and "resourceType" in bundle["response"]["FhirResource"]
):
return bundle["response"]["FhirResource"]["resourceType"] == "Bundle"
return False
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this anticipated to be used? Are we expecting to always get a FHIR Bundle in an HTTP response?



def add_data_source_to_bundle(bundle: dict) -> dict:
"""
This function will search the FHIR bundle being passed as
an argument for specific LOINC codes that indicate a minimum
level of provenance for the source of the data, e.g., ELR,
eICR, RR, and VXU.

:param bundle: The response.FhirResource FHIR bundle to check
for minimum provenance.
:return: The entire FHIR bundle with the new field Meta.source
"""
if is_response_fhirresource(bundle):
# Define the specific LOINC codes
loinc_ecr = "55751-2"
loinc_rr = "88085-6"
loinc_elr = "11502-2"
loinc_vxu = "60484-3"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may not be able to expect or rely on a proper loinc code to be part of the FHIR bundle's being passed in. It may be better to have a parameter for the 'source_data' that can then be 'filtered' based upon a list of proper/expected results (ie... elr, ecr, etc...) and then add that to the resource.meta.source. Just my thoughts.


# Iterate through the "entry" list in the FHIR bundle
for entry in bundle["response"]["FhirResource"]["entry"]:
resource = entry["resource"]
if (
"type" in resource
and "coding" in resource["type"]
and len(resource["type"]["coding"]) > 0
):
loinc_code = resource["type"]["coding"][0].get("code")
if loinc_code == loinc_ecr:
# Insert the new field Meta.source
resource["meta"] = {
"source": "eICR_55751-2_public-health-case-report"
}
elif loinc_code == loinc_rr:
# Insert the new field Meta.source
resource["meta"] = {
"source": "RR_88085-6_reportability-response-report"
}
elif loinc_code == loinc_elr:
# Insert the new field Meta.source
resource["meta"] = {"source": "ELR_11502-2_laboratory-report"}
elif loinc_code == loinc_vxu:
# Insert the new field Meta.source
resource["meta"] = {"source": "VXU_60484-3_cdc-immunization-panel"}

return bundle
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really appreciate the spirit of what we are doing here. However there are few things I think we need to change.

  1. We aren't going to be able to find provenance data within a FHIR bundle, we need to be able to provide a value for provenance data to this function and have it insert the value in resource.meta.
  2. bundle should simply be a FHIR bundle. The response and FhirResource keys are part of the response object from the FHIR converter, but are not part of the FHIR bundle. The FHIR bundle here is simply the value stored in the response.FhirResource key.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with this and it makes sense.

29 changes: 29 additions & 0 deletions tests/fhir/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
find_entries_by_resource_type,
get_field,
get_one_line_address,
is_response_fhirresource,
add_data_source_to_bundle,
)


Expand Down Expand Up @@ -156,3 +158,30 @@ def test_get_one_line_address():
get_one_line_address(address)
== "1234 Silversun Strip Zakera Ward, Citadel 99999"
)


def test_is_response_fhirresource():
# load example response.FhirResource bundle
response_fhirresource = json.load(
open(
pathlib.Path(__file__).parent.parent
/ "examples"
/ "eCR-sample-data"
/ "ecr_sample_results.json"
)
)
# load example FHIR bundle
bundle = json.load(
open(
pathlib.Path(__file__).parent.parent
/ "assets"
/ "general"
/ "patient_bundle.json"
)
)

response_fhirresource_result = is_response_fhirresource(response_fhirresource)
assert response_fhirresource_result == True

bundle_result = is_response_fhirresource(bundle)
assert bundle_result == False