General Usage#

[1]:
%load_ext autoreload
%autoreload 2
%pprint off
Pretty printing has been turned OFF
[2]:
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
[3]:
%pprint
Pretty printing has been turned ON

Preamble#

[!] use only if you haven’t installed FHIR PACK via pip, pipenv or similar in your environment but you have instead cloned the project and are now in the /examples directory

[5]:
import sys,os
sys.path.append(os.getcwd()+'/../src/')
# sys.path

Imports#

[6]:
import fhirpack                     as fp
import pandas                       as pd
import fhirpy
import numpy                        as np
import fhir.resources       as fr
import json
from tqdm import tqdm
from fhirpack.constants import CONFIG

Useful Paths for Data Storage#

[7]:
DATAPATH=CONFIG.get('DATAPATH')
RESPATH=f"{DATAPATH}/fhir/"

FHIR Server Connection#

CLI Usage#

[26]:
!python -m fhirpack.cli -e .env.example "-o" "getPatients" -p "given = Chalmers" #-v

!fp -e .env.example -o "getPatients" -p "given = Chalmers" #-v
                                                data
0  {'resourceType': 'Patient', 'id': '1567099', '...
                                                data
0  {'resourceType': 'Patient', 'id': '1567099', '...

From Custom Environment File#

[27]:
pack = fp.PACK(envFile='.env.example')

for i,e in pack.getPatients(['2918556']).data.items():
    print(
            json.dumps(e.serialize(), indent=4, sort_keys=True)[:200],
            '\n...'
    )

{
    "active": false,
    "address": [
        {
            "city": "[Ljava.lang.String;@6486517a",
            "country": "lJltcNpfGu",
            "district": "kIATSJDTIN",
            "line": [

...

[20]:
!cat .env.example

SCHEMA=http
PORT=80

DOMAIN=${SCHEMA}://hapi.fhir.org

#DOMAIN=${SCHEMA}://example.com:${PORT}
# only use port if the server is running on a non-standard port
# and this is reflected in the FHIR pagination links
# see https://gitlab.com/fhirpack/main/-/issues/75 for more information

APIBASE=${DOMAIN}/baseR4

#AUTH_METHOD=
#AUTH_PARAMS_PRESET=
#LOGINURL=${DOMAIN}/oauth/token
#OAUTH_TOKEN_ENDPOINT=${DOMAIN}/oauth/token
#OAUTH_USERNAME=username
#OAUTH_PASSWORD=password
#OAUTH_TOKEN=token

LOGSPATH=./logs
DATAPATH=./data

#EXTRACTION_BASE_TOKEN_DICOM=${OAUTH_TOKEN}

From Default .env Environment File#

[38]:
# pack = fp.PACK()
# pack.client.authorization

Manual Setup#

[42]:
pack  = fp.PACK("http://hapi.fhir.org/baseR4")
pack.getPatients(['2918556'])

[42]:
data
0 {'resourceType': 'Patient', 'id': '2918556', '...
[ ]:
#testing with another less reliable FHIR server
#
#pack  = fp.PACK("http://test.fhir.org/r4/")
#pack.getPatients(['11']).data.iloc[0]

Testing with A Docker FHIR Server and Synthetic Data#

[ ]:
#run "docker-compose up" in your local clone of FHIRPACK first

# pack  = fp.PACK("http://127.0.0.1:42112/hapi-fhir-jpaserver/fhir")
# pack.getPatients(['1']).data.iloc[0].serialize()

Introductory Example#

[123]:
# for patients whose lastname is Koepp, find the root identity,
# get their associated diagnostic reports and report their ID and status

pack.getPatients(searchParams={"family":"koepp"})\
    .getRootPatients()\
            .explode()\
                    .getDiagnosticReports()\
                            .dropna()\
                                    .gatherSimplePaths(['id','status'])\
                                            .explode(['id','status'])

[123]:
id status
0 None None
1 None None
2 6570895b-5943-430b-8f7b-e5df1ffc6d83 final
2 85d08e59-3e58-4518-be8b-3ccfc15cc9fa final
2 35f7efea-6557-467e-a693-34d73a097f64 final
... ... ...
37 None None
38 None None
39 None None
40 None None
41 1516127 final

104 rows × 2 columns

FHIR PACK Usage#

References#

[44]:
patientReference = pack.getReferences(['Patient/647487'])

patientReference.data.iloc[0].to_resource().serialize()

patientReference.getResources()
[44]:
{'resourceType': 'Patient',
 'id': '647487',
 'meta': {'versionId': '1',
  'lastUpdated': '2020-03-20T21:38:58.974+00:00',
  'source': '#bE19PhJ3nQMhB1xy'},
 'text': {'status': 'generated',
  'div': '<div xmlns="http://www.w3.org/1999/xhtml"><div class="hapiHeaderText">Series_Status: Not complete Evaluation_Status_1.0: Valid Evaluation_Status_2.0: Valid Evaluation_Status_3.0: Valid Evaluation_Status_4.0: Valid Evaluation_Status_5.0: Valid <b># 5 PENTACEL AT ≥ 4 YRS </b></div><table class="hapiPropertyTable"><tbody><tr><td>Date of birth</td><td><span>20 January 2016</span></td></tr></tbody></table></div>'},
 'name': [{'family': '# 5 Pentacel at ≥ 4 yrs',
   'given': ['Series_Status: Not complete',
    'Evaluation_Status_1.0: Valid',
    'Evaluation_Status_2.0: Valid',
    'Evaluation_Status_3.0: Valid',
    'Evaluation_Status_4.0: Valid',
    'Evaluation_Status_5.0: Valid']}],
 'gender': 'female',
 'birthDate': '2016-01-20'}

[44]:
data
0 {'resourceType': 'Patient', 'id': '647487', 'm...

Resources#

Reference to Resource#

[45]:
multiPatientReference = pack.getReferences(
    [
        'Patient/1849165',
        'Patient/647487'
    ])

multiPatientReference.data.apply( lambda x:x.id )
[45]:
0    1849165
1     647487
Name: data, dtype: object

Direct Resource#

[46]:
pack.getPatients(searchParams={"family":"Betterhalf"})

[46]:
data
0 {'resourceType': 'Patient', 'id': '2080537', '...
1 {'resourceType': 'Patient', 'id': '2080822', '...
2 {'resourceType': 'Patient', 'id': '2153287', '...
3 {'resourceType': 'Patient', 'id': '619088', 'm...
4 {'resourceType': 'Patient', 'id': '2548478', '...
5 {'resourceType': 'Patient', 'id': '2548794', '...
6 {'resourceType': 'Patient', 'id': '2737336', '...
7 {'resourceType': 'Patient', 'id': '1376090', '...
8 {'resourceType': 'Patient', 'id': '1376092', '...
9 {'resourceType': 'Patient', 'id': '1377059', '...
10 {'resourceType': 'Patient', 'id': '1377093', '...
11 {'resourceType': 'Patient', 'id': '1388633', '...
[52]:
pack.getPatients(searchParams={"family":"Betterhalf"}).size

[52]:
12
[48]:
multiPatientResource = pack.getResources(
    ['Patient/1849165',
     'Patient/647487']
)

multiPatientResource

[48]:
data
0 {'resourceType': 'Patient', 'id': '1849165', '...
1 {'resourceType': 'Patient', 'id': '647487', 'm...

Serialization and Element Access#

[49]:
patientResource = patientReference.data.iloc[0].to_resource()

patientResource['name'][0]['given']

patientResource.serialize().get('birthDate')
[49]:
['Series_Status: Not complete',
 'Evaluation_Status_1.0: Valid',
 'Evaluation_Status_2.0: Valid',
 'Evaluation_Status_3.0: Valid',
 'Evaluation_Status_4.0: Valid',
 'Evaluation_Status_5.0: Valid']
[49]:
'2016-01-20'
[50]:
multiPatientReference.getResources()

[50]:
data
0 {'resourceType': 'Patient', 'id': '1849165', '...
1 {'resourceType': 'Patient', 'id': '647487', 'm...
[51]:
multiPatientResource[:1].pretty
{
    "_birthDate": {
        "extension": [
            {
                "url": "http://hl7.org/fhir/StructureDefinition/patient-birthTime",
                "valueDateTime": "1974-12-25T14:35:45-05:00"
            }
        ]
    },
    "active": true,
    "address": [
        {
            "city": "PleasantVille",
            "district": "Rainbow",
            "line": [
                "534 Erewhon St"
            ],
            "period": {
                "start": "1974-12-25"
            },
            "postalCode": "3999",
            "state": "Vic",
            "text": "534 Erewhon St PeasantVille, Rainbow, Vic  3999",
            "type": "both",
            "use": "home"
        }
    ],
    "birthDate": "1974-12-25",
    "contact": [
        {
            "address": {
                "city": "PleasantVille",
                "district": "Rainbow",
                "line": [
                    "534 Erewhon St"
                ],
                "period": {
                    "start": "1974-12-25"
                },
                "postalCode": "3999",
                "state": "Vic",
                "type": "both",
                "use": "home"
            },
            "gender": "female",
            "name": {
                "_family": {
                    "extension": [
                        {
                            "url": "http://hl7.org/fhir/StructureDefinition/humanname-own-prefix",
                            "valueString": "VV"
                        }
                    ]
                },
                "family": "du March\u00e9",
                "given": [
                    "B\u00e9n\u00e9dicte"
                ]
            },
            "period": {
                "start": "2012"
            },
            "relationship": [
                {
                    "coding": [
                        {
                            "code": "N",
                            "system": "http://terminology.hl7.org/CodeSystem/v2-0131"
                        }
                    ]
                }
            ],
            "telecom": [
                {
                    "system": "phone",
                    "value": "+33 (237) 998327"
                }
            ]
        }
    ],
    "deceasedBoolean": false,
    "gender": "male",
    "id": "1849165",
    "identifier": [
        {
            "assigner": {
                "display": "Acme Healthcare"
            },
            "period": {
                "start": "2001-05-06"
            },
            "system": "urn:oid:1.2.36.146.595.217.0.1",
            "type": {
                "coding": [
                    {
                        "code": "MR",
                        "system": "http://terminology.hl7.org/CodeSystem/v2-0203"
                    }
                ]
            },
            "use": "usual",
            "value": "12345"
        }
    ],
    "managingOrganization": {
        "reference": "Organization/1845391"
    },
    "meta": {
        "lastUpdated": "2021-02-08T21:42:25.829+00:00",
        "source": "#PBPO58xnJNERsS1A",
        "versionId": "1"
    },
    "name": [
        {
            "family": "Chalmers",
            "given": [
                "Peter",
                "James"
            ],
            "use": "official"
        },
        {
            "given": [
                "Jim"
            ],
            "use": "usual"
        },
        {
            "family": "Windsor",
            "given": [
                "Peter",
                "James"
            ],
            "period": {
                "end": "2002"
            },
            "use": "maiden"
        }
    ],
    "resourceType": "Patient",
    "telecom": [
        {
            "use": "home"
        },
        {
            "rank": 1,
            "system": "phone",
            "use": "work",
            "value": "(03) 5555 6473"
        },
        {
            "rank": 2,
            "system": "phone",
            "use": "mobile",
            "value": "(03) 3410 5613"
        },
        {
            "period": {
                "end": "2014"
            },
            "system": "phone",
            "use": "old",
            "value": "(03) 5555 8834"
        }
    ],
    "text": {
        "div": "<div xmlns=\"http://www.w3.org/1999/xhtml\">\n\t\t\t<table>\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Name</td>\n\t\t\t\t\t\t<td>Peter James \n              <b>Chalmers</b> (&quot;Jim&quot;)\n            </td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Address</td>\n\t\t\t\t\t\t<td>534 Erewhon, Pleasantville, Vic, 3999</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Contacts</td>\n\t\t\t\t\t\t<td>Home: unknown. Work: (03) 5555 6473</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Id</td>\n\t\t\t\t\t\t<td>MRN: 12345 (Acme Healthcare)</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\t\t</div>",
        "status": "generated"
    }
}
[58]:
pack.getDiagnosticReports(
    ['Patient/647487']
)[:1].keys


resourceType
id
meta
meta.versionId
meta.lastUpdated
meta.source
text
text.status
text.div
name
name.family
name.given
gender
birthDate

DataFrame Operations#

[59]:
multiPatientReference[:1]

multiPatientReference[-1:]

multiPatientReference.values

multiPatientReference.info()
[59]:
data
0 {'reference': 'Patient/1849165'}
[59]:
data
1 {'reference': 'Patient/647487'}
[59]:
array([[<SyncFHIRReference Patient/1849165>],
       [<SyncFHIRReference Patient/647487>]], dtype=object)
<class 'fhirpack.base.Frame'>
RangeIndex: 2 entries, 0 to 1
Data columns (total 1 columns):
 #   Column  Non-Null Count  Dtype
---  ------  --------------  -----
 0   data    2 non-null      object
dtypes: object(1)
memory usage: 144.0+ bytes

pack.base.Frame#

[60]:
fp.base.Frame( [[patientResource]], columns=['data'])
[60]:
data
0 {'resourceType': 'Patient', 'id': '647487', 'm...

Extraction#

Patient Extraction#

fhirpack.extraction.getPatients#

[61]:
pack.getPatients(
    [
            '647487'
    ]
)


[61]:
data
0 {'resourceType': 'Patient', 'id': '647487', 'm...
[62]:
pack.getPatients(
    [
            '647487'
    ]
).data.item().serialize()

[62]:
{'resourceType': 'Patient',
 'id': '647487',
 'meta': {'versionId': '1',
  'lastUpdated': '2020-03-20T21:38:58.974+00:00',
  'source': '#bE19PhJ3nQMhB1xy'},
 'text': {'status': 'generated',
  'div': '<div xmlns="http://www.w3.org/1999/xhtml"><div class="hapiHeaderText">Series_Status: Not complete Evaluation_Status_1.0: Valid Evaluation_Status_2.0: Valid Evaluation_Status_3.0: Valid Evaluation_Status_4.0: Valid Evaluation_Status_5.0: Valid <b># 5 PENTACEL AT ≥ 4 YRS </b></div><table class="hapiPropertyTable"><tbody><tr><td>Date of birth</td><td><span>20 January 2016</span></td></tr></tbody></table></div>'},
 'name': [{'family': '# 5 Pentacel at ≥ 4 yrs',
   'given': ['Series_Status: Not complete',
    'Evaluation_Status_1.0: Valid',
    'Evaluation_Status_2.0: Valid',
    'Evaluation_Status_3.0: Valid',
    'Evaluation_Status_4.0: Valid',
    'Evaluation_Status_5.0: Valid']}],
 'gender': 'female',
 'birthDate': '2016-01-20'}
[63]:
for i,e in pack.getPatients(['647487','1849165']).itertuples():
    print (f"Row {i} with Patient ID {e.id}")

Row 0 with Patient ID 647487
Row 1 with Patient ID 1849165

[64]:
getPatientsAsList=pack.getPatients(['647487','1849165']).cast('list')

getPatientsAsList

[64]:
[[<SyncFHIRResource Patient/647487>], [<SyncFHIRResource Patient/1849165>]]
[65]:
[e.pop().id for e in getPatientsAsList]
[65]:
['647487', '1849165']

Patients as Operand and Extracting other Resources#

[66]:
patients = pack.getPatients(
    ['9ac622c4-61c8-40b4-b6d9-06cfeb3d6995',
    '1849165',
    '649231',
    '650224']
)


fhirpack.extraction.getRootPatient#

[68]:
patients.getRootPatients()
[68]:
data
0 [{'resourceType': 'Patient', 'id': '9ac622c4-6...
1 [{'resourceType': 'Patient', 'id': '1849165', ...
2 [{'resourceType': 'Patient', 'id': '649231', '...
3 [{'resourceType': 'Patient', 'id': '650224', '...
[67]:
pack.getRootPatients(
    [
        'b558da74-7756-4845-87d5-d1cca8b79a62',
    ],
).explode().gatherSimplePaths(["id"]).id.unique()

[67]:
array(['9ac622c4-61c8-40b4-b6d9-06cfeb3d6995'], dtype=object)
[69]:
pack.getResources(
    [
            'Patient/b558da74-7756-4845-87d5-d1cca8b79a62'
    ]
).getRootPatients()

[69]:
data
0 [{'resourceType': 'Patient', 'id': '9ac622c4-6...
[70]:
rootPatients = patients.getResources().getRootPatients().explode()

rootPatients.gatherSimplePaths(['id','birthDate'])

[70]:
id birthDate
0 9ac622c4-61c8-40b4-b6d9-06cfeb3d6995 1981-01-01
1 1849165 1974-12-25
2 649231 2018-12-21
3 650224 2007-02-08
[71]:
rootPatients.data[0].name
[71]:
[{'family': 'TestFamily', 'given': ['TestGiven']}]
[72]:
for link in rootPatients.data[0]['link']:
    lpat=link.other.to_resource()
    print(lpat.id)
b558da74-7756-4845-87d5-d1cca8b79a62

fhirpack.extraction.getLinkedPatients#

[73]:
pack.getLinkedPatients(
    [
            '9ac622c4-61c8-40b4-b6d9-06cfeb3d6995',
    ]
)

[73]:
data
0 [{'resourceType': 'Patient', 'id': 'b558da74-7...

fhirpack.extraction.getConditions#

Conditions#

[74]:
conditions = pack.getConditions(
    searchParams={
            'code':'44465007',
            '_sort': '-onset-date',
    }
)[:5]

conditions

[74]:
data
0 {'resourceType': 'Condition', 'id': '1584692',...
1 {'resourceType': 'Condition', 'id': '1591180',...
2 {'resourceType': 'Condition', 'id': '1402386',...
3 {'resourceType': 'Condition', 'id': '1403562',...
4 {'resourceType': 'Condition', 'id': '1495528',...

Patients for Conditions#

[75]:
conditions.getPatients().explode().gatherSimplePaths(['id','name.given','name.family'])


[75]:
id name.given name.family
0 1583909 [[Shayne60]] [Miller503]
1 1590885 [[Ty725]] [Sporer811]
2 1402076 [[Phyliss]] [Nyambura]
3 1403421 [[Stefania]] [Bethwell]
4 1495412 [[Hallie315], [Hallie315]] [Donnelly343, Osinski784]
[76]:
conditions\
    .getPatients()\
            .explode()\
                    .data.apply(lambda x:x.id)\
                            .to_csv(f"data.ignore")

[77]:
!cat data.ignore
,data
0,1583909
1,1590885
2,1402076
3,1403421
4,1495412
[78]:
conditions = pd.read_csv( f"data.ignore", index_col=0)
conditions.shape
conditions
[78]:
(5, 1)
[78]:
data
0 1583909
1 1590885
2 1402076
3 1403421
4 1495412

Conditions for Patient#

[79]:
pack.getPatients(['8cbf1128-3644-47a1-9cc8-05f1aac6071d']).getConditions().explode()

[79]:
data
0 {'resourceType': 'Condition', 'id': '2b7a4d69-...
0 {'resourceType': 'Condition', 'id': '0fc73e7c-...
0 {'resourceType': 'Condition', 'id': 'cb1bab6c-...
0 {'resourceType': 'Condition', 'id': 'bc301bbf-...
0 {'resourceType': 'Condition', 'id': '5db4866a-...

fhipack.extraction.getEpisodesOfCare#

[80]:
rootPatients[:2]
[80]:
data
0 {'resourceType': 'Patient', 'id': '9ac622c4-61...
1 {'resourceType': 'Patient', 'id': '1849165', '...
[81]:
pack.getPatients(['P0522-patientBSJ1']).getEpisodesOfCare()

[81]:
data
0 [{'resourceType': 'EpisodeOfCare', 'id': 'P052...

fhipack.extraction.getFamilyMemberHistories#

[82]:
pack.getPatients(['Patient/2866670']).getFamilyMemberHistories()

[82]:
data
0 [{'resourceType': 'FamilyMemberHistory', 'id':...

fhipack.extraction.getMedicationAdministrations#

[83]:
pack.getPatients(['Patient/31678']).getMedicationAdministrations()[:5]

[83]:
data
0 [{'resourceType': 'MedicationAdministration', ...

fhipack.extraction.getMedicationRequests#

[84]:
pack.getPatients(['Patient/202205uscore-patient-example-1']).getMedicationRequests().explode()

[84]:
data
0 {'resourceType': 'MedicationRequest', 'id': '2...
0 {'resourceType': 'MedicationRequest', 'id': '2...
0 {'resourceType': 'MedicationRequest', 'id': '2...

fhipack.extraction.getObservations#

[85]:
pack\
    .getPatients(['Patient/258974'])\
            .getConditions(searchParams={"code":"44465007"})\
                    .explode()\
                            .getPatients(searchParams={"family":"Keebler762"})

[85]:
data
0 [{'resourceType': 'Patient', 'id': '258974', '...
[86]:

from datetime import datetime interesting = pack.getPatients(['Patient/2164033']).\ getObservations( searchParams={ "code":"http ://loinc.org|29463-7", } )\ .gatherSimplePaths(['id','issued','code.coding.code'])\ .explode(['id','issued','code.coding.code']) interesting.issued = pd.to_datetime(interesting.issued).dropna().apply(lambda x:x.replace(tzinfo=None)) interesting[interesting.issued> datetime.fromisoformat('2021-01-01T00:00:00')]

[86]:
id issued code.coding.code
0 2164039 2021-06-05 05:30:23.291 [29463-7]

fhirpack.extraction.getDiagnosticReports#

[87]:
diagnosticReports=pack\
    .getPatients(["Patient/9b8c1901-62ee-48a7-8229-b771d59f1e5f"])\
            .getDiagnosticReports(
                    searchParams={}
                    )\
                    .explode()

diagnosticReports

[87]:
data
0 {'resourceType': 'DiagnosticReport', 'id': '12...
0 {'resourceType': 'DiagnosticReport', 'id': '5a...
0 {'resourceType': 'DiagnosticReport', 'id': '2d...
0 {'resourceType': 'DiagnosticReport', 'id': '01...
0 {'resourceType': 'DiagnosticReport', 'id': '47...
0 {'resourceType': 'DiagnosticReport', 'id': 'b1...
0 {'resourceType': 'DiagnosticReport', 'id': '58...
0 {'resourceType': 'DiagnosticReport', 'id': '87...
0 {'resourceType': 'DiagnosticReport', 'id': '8c...
0 {'resourceType': 'DiagnosticReport', 'id': 'ac...
0 {'resourceType': 'DiagnosticReport', 'id': 'bc...
0 {'resourceType': 'DiagnosticReport', 'id': 'bf...
[88]:
paths=[
    "subject",
    "presentedForm.contentType",
    "presentedForm.data",
    "presentedForm.url",
    "presentedForm.title",
    "presentedForm.creation"
]



diagnosticReports=pack.getDiagnosticReports(
    searchParams={
            "_id":"19bdf90a-8ca4-4921-8aeb-2bf3423aaf09",
            # "identifier":"|",
            # "_content":"covid19",
            # "code":"|",
            # "issued__gt":"2010-01-01",
            # "issued__lt":"2011-01-01"
    }
)

diagnosticReports.gatherSimplePaths(paths)

[88]:
subject presentedForm.contentType presentedForm.data presentedForm.url presentedForm.title presentedForm.creation
0 {'reference': 'Patient/e92abcdc-a300-41e0-aa0f... [text/plain] [Q2pJd01UQXRNVEV0TVRNS0NpTWdRMmhwWldZZ1EyOXRjR... None None None

fhirpack.extraction.getURLBytes#

[89]:
paths=[
    'id',
    'subject.reference',
    'presentedForm.url'
]

diagnosticReports = pack.getPatients(
    ['Patient/e92abcdc-a300-41e0-aa0f-378daebe25dc']
    )\
        .getDiagnosticReports()[:10]

diagnosticReports=diagnosticReports.gatherSimplePaths(paths)
diagnosticReports=diagnosticReports.explode('presentedForm.url')
diagnosticReports

# diagnosticReports['path']=diagnosticReports['id']+'_'+diagnosticReports['presentedForm.url'].str.split('/').str[-1:].str[0]
# diagnosticReports['data']=diagnosticReports.getURLBytes(operateOnCol='presentedForm.url')
# diagnosticReports.sendBytesToFile()

[89]:
id subject.reference presentedForm.url
0 [1ca4c411-116d-49d7-82e0-cde6bff90cfd, 126df18... [Patient/e92abcdc-a300-41e0-aa0f-378daebe25dc,... None
[93]:
diagnosticReports.loc[:, diagnosticReports.columns!='data'][:5]
[93]:
id subject.reference presentedForm.url
0 [1ca4c411-116d-49d7-82e0-cde6bff90cfd, 126df18... [Patient/e92abcdc-a300-41e0-aa0f-378daebe25dc,... None

fhirpack.extraction.base.getAbsolutePaths#

[98]:
absolutePaths=[
#    'Condition.code.coding.code',
   'Condition.id',
    'Condition.subject.reference',
    'Encounter.id',
    'Encounter.participant.individual.reference',
#     'Procedure.code.coding.display',
#     'Procedure.code.coding.code',
    'Procedure.id',
    'Procedure.status',
    'Procedure.performedDateTime'
]

pack.client

result=pack.getPatients(
    ['Patient/e92abcdc-a300-41e0-aa0f-378daebe25dc']
).getAbsolutePaths(absolutePaths)
[98]:
<SyncFHIRClient http://hapi.fhir.org/baseR4>

[99]:
result['Procedure']
[99]:
Procedure.id Procedure.performedDateTime Procedure.status
0 f262bafb-789a-44a1-9453-c21065abc4d1 None completed
1 e65c5378-5d1a-4978-9590-c6c8846dd6d0 None completed
[100]:
paths=[
    'valueQuantity.value',
    'valueQuantity.unit',
    'valueQuantity.system',
    'valueQuantity.code',
]
[101]:
pack.\
    getPatients(['e92abcdc-a300-41e0-aa0f-378daebe25dc'])\
            .getObservations()\
                    .explode()\
                            .gatherSimplePaths(paths)

[101]:
valueQuantity.value valueQuantity.unit valueQuantity.system valueQuantity.code
0 None None None None
[102]:
result["Condition"]
[102]:
Condition.id Condition.subject.reference
0 b8a1a1c4-f973-4b6b-a0ea-3d04bc4c8823 Patient/e92abcdc-a300-41e0-aa0f-378daebe25dc
[103]:
result["Encounter"]
[103]:
Encounter.id Encounter.participant.individual.reference
0 b9f19065-c8e6-40b9-b368-b09a8fb9a8d6 [Practitioner/00000171-0929-2892-0000-00000001...
1 174d8c79-5517-4f80-967f-3939f943b2c8 [Practitioner/00000171-0929-2892-0000-00000001...
2 3f3a061a-5df2-4dc0-872c-e1e4b88955a1 [Practitioner/00000171-0929-2892-0000-00000001...
3 2b8cb0e7-5b1e-4769-a418-bf9e6dd86611 [Practitioner/00000171-0929-2892-0000-00000001...
4 36fb900c-9ff7-4131-812c-536ab50a0a5c [Practitioner/00000171-0929-2892-0000-00000000...
5 9911ef15-1b9a-4fbd-b95d-05bd4f060269 [Practitioner/00000171-0929-2892-0000-00000001...
6 f3b1e501-aac6-4480-bf35-38474563069a [Practitioner/00000171-0929-2892-0000-00000001...
7 969f9166-4f9a-4be6-9257-ed00b295a408 [Practitioner/00000171-0929-2892-0000-00000001...
8 806264f4-4f45-4105-a5bc-8e9a9c49b119 [Practitioner/00000171-0929-2892-0000-00000001...
9 40166ee5-0bc3-4819-96c9-e07dd26e938b [Practitioner/00000171-0929-2892-0000-00000001...
10 48f082f8-b46c-4127-a1b4-8e3c1d71a132 [Practitioner/00000171-0929-2892-0000-00000001...
[104]:
result["Procedure"]
[104]:
Procedure.id Procedure.performedDateTime Procedure.status
0 f262bafb-789a-44a1-9453-c21065abc4d1 None completed
1 e65c5378-5d1a-4978-9590-c6c8846dd6d0 None completed
[105]:
result['Encounter'].explode(
    'Encounter.participant.individual.reference'
)\
    .rename(
            columns={"Encounter.participant.individual.reference":"data"}
            )\
                    .dropna()\
                            .getResources()[:5]\
                                    .gatherSimplePaths(['name.given','name.family'])

[105]:
name.given name.family
0 [[Willy639]] [Rutherford999]
1 [[Willy639]] [Rutherford999]
2 [[Willy639]] [Rutherford999]
3 [[Willy639]] [Rutherford999]
4 [[Lilla884]] [Mills423]

fhirpack.extraction.getImagingStudies#

[106]:
conds=pack.getConditions(
    searchParams={
            "code":"C61",
            # "_content": "leber"
    }
    )
conds

[106]:
data
0 {'resourceType': 'Condition', 'id': '1849657',...
[107]:
pack\
    .getImagingStudies(searchParams={"endpoint:missing":False})\
            .gatherSimplePaths(['series.description','series.uid','identifier.value'])

# use .getDICOMInstances().sendDICOMToFiles() to download DICOM files

[107]:
series.description series.uid identifier.value
0 None [IdType-2] [Identifier-117]
1 None [IdType-5] [Identifier-118]
2 None None None
3 None [1.2.276.0.7230010.3.1.3.8323329.10.1594989066... [urn:oid:1.2.826.0.1.3680043.8.498.94636677472...

Transformation#

fhirpack.transformation.base.gatherKeys#

[108]:
patients.gatherKeys().data.explode().value_counts()[:10]
[108]:
name.given        6
name.family       5
telecom.use       5
resourceType      4
id                4
telecom.system    4
gender            4
name              4
birthDate         4
telecom.value     4
Name: data, dtype: int64
[109]:
pack.getPatients(
    ['e92abcdc-a300-41e0-aa0f-378daebe25dc']
    )\
        .gatherKeys(['valueString'])\
            .explode()

[109]:
data
0 resourceType
0 id
0 meta
0 meta.versionId
0 meta.lastUpdated
... ...
0 communication.language.coding
0 communication.language.coding.system
0 communication.language.coding.code
0 communication.language.coding.display
0 communication.language.text

118 rows × 1 columns

fhirpack.transformation.base.valuesForKeys#

[110]:
pack.getPatients(
    ['e92abcdc-a300-41e0-aa0f-378daebe25dc'],
    # includeLinkedPatients=True
    )\
        .gatherValuesForKeys(['valueString'])\
            .explode()

[110]:
data
0 White
0 Not Hispanic or Latino
0 Nanci249 Gleichner915

fhirpack.transformation.base.gatherReferences#

[111]:
pack.gatherReferences(
    ['Patient/9ac622c4-61c8-40b4-b6d9-06cfeb3d6995']
    , recursive=True
)
[111]:
referencer referencee
0 {'reference': 'Patient/9ac622c4-61c8-40b4-b6d9... [Patient/b558da74-7756-4845-87d5-d1cca8b79a62]
1 {'reference': 'Patient/b558da74-7756-4845-87d5... []

fhirpack.transformation.base.gatherText#

[113]:
pack.getPatients(
    ['Patient/1555106'],
    )\
        .getObservations()[:5]\
            .explode()\
                .gatherText()

[113]:
data
0 [laboratory, Alkaline phosphatase [Enzymatic a...
1 [laboratory, Protein [Mass/volume] in Serum or...
2 [laboratory, Glomerular filtration rate/1.73 s...
3 [laboratory, 31.211, MCH [Entitic mass] by Aut...
4 [laboratory, Carbon dioxide, total [Moles/volu...
... ...
672 [2.7168, laboratory, Basophils/100 leukocytes ...
673 [Monocytes [#/volume] in Blood by Automated co...
674 [1.1423, laboratory, Lymphocytes [#/volume] in...
675 [Platelets [#/volume] in Blood by Automated co...
676 [laboratory, 12.922, Erythrocyte distribution ...

677 rows × 1 columns

fhirpack.transformation.base.gatherDates#

[115]:
pack.getPatients(
    ['Patient/1555106'],
    )\
        .getObservations()[:5]\
            .explode()\
                .gatherValuesForKeys(['issued'])

[115]:
data
0 [2020-03-18T21:53:14.197-04:00]
1 [2020-03-19T21:53:14.197-04:00]
2 [2020-03-19T21:53:14.197-04:00]
3 [2020-03-14T21:53:14.197-04:00]
4 [2020-03-19T21:53:14.197-04:00]
... ...
672 [2020-03-20T21:53:14.197-04:00]
673 [2020-03-20T21:53:14.197-04:00]
674 [2020-03-20T21:53:14.197-04:00]
675 [2020-03-20T21:53:14.197-04:00]
676 [2020-03-20T21:53:14.197-04:00]

677 rows × 1 columns

[116]:
pack.getPatients(
    ['Patient/1555106'],
    )\
        .getObservations()[:5]\
            .explode()\
                .gatherDates()

[116]:
dates
0 [2020-03-18T21:53:14-04:00, 2020-03-18T21:53:1...
1 [2020-03-19T21:53:14-04:00, 2020-03-19T21:53:1...
2 [2020-03-19T21:53:14-04:00, 2020-03-19T21:53:1...
3 [2020-03-14T21:53:14-04:00, 2020-03-14T21:53:1...
4 [2020-03-19T21:53:14-04:00, 2020-03-19T21:53:1...
... ...
672 [2020-03-20T21:53:14-04:00, 2020-03-20T21:53:1...
673 [2020-03-20T21:53:14-04:00, 2020-03-20T21:53:1...
674 [2020-03-20T21:53:14-04:00, 2020-03-20T21:53:1...
675 [2020-03-20T21:53:14-04:00, 2020-03-20T21:53:1...
676 [2020-03-20T21:53:14-04:00, 2020-03-20T21:53:1...

677 rows × 1 columns

Load#

[117]:
pack.validate(
    ['Patient/1555106']
    )\
        .sendResourcesToFiles(['./data.ignore'])
[117]:
array([ True])

Utils#

Server Profiling#

[118]:
pack.countServerResources()
[118]:
resourceType count
0 Account 510
1 ActivityDefinition 284
2 AdverseEvent 116
3 AllergyIntolerance 9356
4 Appointment 29636
... ... ...
141 TestReport 11
142 TestScript 33
143 ValueSet 3126
144 VerificationResult 9
145 VisionPrescription 15

146 rows × 2 columns

Validation#

[119]:
pack.validate(
    ['Patient/1555106']
)

[119]:
data
0 {'resourceType': 'Patient', 'id': '1555106', '...

FHIR PACK Internals#

FHIRPy#

URL Parsing#

[120]:
import fhirpy.base.utils as fpu
url=fpu.parse_pagination_url('/app/FHIR/r4/Condition?code=C61&_count=1&_sort=-onset-date&identifier=%7C&_Pagination=eyJvZmZzZXQiOjIwfQ%3D%3D')
url
[120]:
('/app/FHIR/r4/Condition',
 {'code': ['C61'],
  '_count': ['1'],
  '_sort': ['-onset-date'],
  'identifier': ['|'],
  '_Pagination': ['eyJvZmZzZXQiOjIwfQ==']})

Raw fetch_resource()#

[121]:
pack.client._fetch_resource(
    "Condition/1499041"
)
[121]:
{'resourceType': 'Condition',
 'id': '1499041',
 'meta': {'versionId': '1',
  'lastUpdated': '2020-10-05T16:29:07.960+00:00',
  'source': '#0sjLd8ZeFHHrRHaX'},
 'clinicalStatus': {'coding': [{'system': 'http://terminology.hl7.org/CodeSystem/condition-clinical',
    'code': 'active'}]},
 'verificationStatus': {'coding': [{'system': 'http://terminology.hl7.org/CodeSystem/condition-ver-status',
    'code': 'confirmed'}]},
 'category': [{'coding': [{'system': 'http://terminology.hl7.org/CodeSystem/condition-category',
     'code': 'encounter-diagnosis',
     'display': 'Encounter Diagnosis'}]}],
 'code': {'coding': [{'system': 'http://snomed.info/sct',
    'code': '22298006',
    'display': 'Myocardial Infarction'}],
  'text': 'Myocardial Infarction'},
 'subject': {'reference': 'Patient/1465609'},
 'onsetDateTime': '2020-04-01T09:52:49-04:00',
 'recordedDate': '2020-04-01T09:52:49-04:00',
 'asserter': {'reference': 'Practitioner/1498740'}}

Raw client.execute()#

[133]:
pack.client.execute('Condition',
method='get',
params={
    'code':'C61',
    '_sort':'-onset-date',
    '_count': 1,
    '_total':'accurate'
}
).total

pack.client.execute(
    'DiagnosticReport/_search',
    method="post",
    data={"_id": "9fa9ab4c-9e1c-46c9-9bec-ec01b3215716"},
    params={"_count": 1},
)
[133]:
1
[133]:
{'resourceType': 'Bundle',
 'id': 'ba7c0ad0-cb78-4909-8564-13fe58f5fec1',
 'meta': {'lastUpdated': '2022-06-23T08:25:02.930+00:00'},
 'type': 'searchset',
 'link': [{'relation': 'self',
   'url': 'http://hapi.fhir.org/baseR4/DiagnosticReport/_search'},
  {'relation': 'next',
   'url': 'http://hapi.fhir.org/baseR4?_getpages=ba7c0ad0-cb78-4909-8564-13fe58f5fec1&_getpagesoffset=1&_count=1&_pretty=true&_bundletype=searchset'}],
 'entry': [{'fullUrl': 'http://hapi.fhir.org/baseR4/DiagnosticReport/3090108',
   'resource': {'resourceType': 'DiagnosticReport',
    'id': '3090108',
    'meta': {'versionId': '4',
     'lastUpdated': '2022-06-23T06:53:13.631+00:00',
     'source': 'http://hl7.org/fhir/StructureDefinition/uri#uJONmcfcpMBdbD2s',
     'profile': ['https://www.medizininformatik-initiative.de/fhir/core/modul-labor/StructureDefinition/DiagnosticReportLab']},
    'text': {'status': 'generated',
     'div': '<div xmlns="http://www.w3.org/1999/xhtml"><div class="hapiHeaderText"> EKGR </div><table class="hapiPropertyTable"><tbody><tr><td>Status</td><td>FINAL</td></tr></tbody></table></div>'},
    'identifier': [{'type': {'coding': [{'system': 'http://terminology.hl7.org/CodeSystem/v2-0203',
         'code': 'FILL'}]},
      'system': 'http://ukgm.de/fhir/NameSpace/akedis/DiagnosticReport',
      'value': 'SEMA_250351055836748624'}],
    'status': 'final',
    'category': [{'coding': [{'system': 'http://terminology.hl7.org/CodeSystem/v2-0074',
        'code': 'EC'}]}],
    'code': {'coding': [{'system': 'https://loinc.org/search/?t=1&s=11524-6+',
       'code': '11524-6',
       'display': 'EKGR'}]},
    'subject': {'reference': 'Patient/3909181'},
    'result': [{'reference': 'Observation/3909182'},
     {'reference': 'Observation/3909183'},
     {'reference': 'Observation/3909184'},
     {'reference': 'Observation/3909185'},
     {'reference': 'Observation/3909186'},
     {'reference': 'Observation/3909187'},
     {'reference': 'Observation/3909188'},
     {'reference': 'Observation/3909189'},
     {'reference': 'Observation/3909190'}]},
   'search': {'mode': 'match'}}]}

Customization#

fhirpack.custom.extraction.base#

[ ]:
# the fhirpack.custom package is guaranteed to never be used by us
# use it to customize fhirpack

# pack.unimplementedPluginBaseExtractorMethod()
# pack.unimplementedPluginBaseTransformerMethod()
# pack.unimplementedPluginBaseLoaderMethod()

# pack.unimplementedPluginSampleExtractorMethod()
# pack.unimplementedPluginSampleTransformerMethod()
# pack.unimplementedPluginSampleLoaderMethod()