Gravitate Health FHIR Implementation Guide
0.1.0 - CI Build

Gravitate Health FHIR Implementation Guide, published by Gravitate Health Project. This guide is not an authorized publication; it is the continuous build for version 0.1.0 built by the FHIR (HL7® FHIR® Standard) CI Build. This version is based on the current content of https://github.com/hl7-eu/gravitate-health/ and changes regularly. See the Directory of published versions

: pregnancy-lens - TTL Representation

Draft as of 2024-06-12

Raw ttl | Download


@prefix fhir: <http://hl7.org/fhir/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

# - resource -------------------------------------------------------------------

 a fhir:Library ;
  fhir:nodeRole fhir:treeRoot ;
  fhir:id [ fhir:v "pregnancy-lens"] ; # 
  fhir:meta [
fhir:versionId [ fhir:v "1" ] ;
fhir:lastUpdated [ fhir:v "2024-06-12T12:30:09.424+00:00"^^xsd:dateTime ] ;
fhir:source [ fhir:v "#8e0ccded-206a-96"^^xsd:anyURI ] ;
    ( fhir:profile [
fhir:v "http://hl7.eu/fhir/ig/gravitate-health/StructureDefinition/lens"^^xsd:anyURI ;
fhir:link <http://hl7.eu/fhir/ig/gravitate-health/StructureDefinition/lens>     ] )
  ] ; # 
  fhir:text [
fhir:status [ fhir:v "generated" ] ;
fhir:div "<div xmlns=\"http://www.w3.org/1999/xhtml\"><p class=\"res-header-id\"><b>Generated Narrative: Library pregnancy-lens</b></p><a name=\"pregnancy-lens\"> </a><a name=\"hcpregnancy-lens\"> </a><a name=\"pregnancy-lens-en-US\"> </a><div style=\"display: inline-block; background-color: #d9e0e7; padding: 6px; margin: 4px; border: 1px solid #8da1b4; border-radius: 5px; line-height: 60%\"><p style=\"margin-bottom: 0px\">version: 1; Last updated: 2024-06-12 12:30:09+0000; </p><p style=\"margin-bottom: 0px\">Information Source: #8e0ccded-206a-96</p><p style=\"margin-bottom: 0px\">Profile: <a href=\"StructureDefinition-lens.html\">Lens Profile</a></p></div><h2>Parameters</h2><table class=\"grid\"><tr><td/><td>in</td><td/><td/><td>CodeableConcept</td><td>parameter if it exists</td></tr></table><h2>Contents</h2><p><code>application/javascript</code></p><pre><code>let pvData = pv;\nlet htmlData = html;\n\nlet epiData = epi;\nlet ipsData = ips;\n\nlet getSpecification = () =&gt; {\n    return &quot;1.0.0&quot;;\n};\n\nlet annotationProcess = (listOfCategories, enhanceTag, document, response) =&gt; {\n    listOfCategories.forEach((check) =&gt; {\n        if (response.includes(check)) {\n            let elements = document.getElementsByClassName(check);\n            for (let i = 0; i &lt; elements.length; i++) {\n                elements[i].classList.add(enhanceTag);\n            }\n            if (document.getElementsByTagName(&quot;head&quot;).length &gt; 0) {\n                document.getElementsByTagName(&quot;head&quot;)[0].remove();\n            }\n            if (document.getElementsByTagName(&quot;body&quot;).length &gt; 0) {\n                response = document.getElementsByTagName(&quot;body&quot;)[0].innerHTML;\n                console.log(&quot;Response: &quot; + response);\n            } else {\n                console.log(&quot;Response: &quot; + document.documentElement.innerHTML);\n                response = document.documentElement.innerHTML;\n            }\n        }\n    });\n\n    if (response == null || response == &quot;&quot;) {\n        throw new Error(\n            &quot;Annotation proccess failed: Returned empty or null response&quot;\n        );\n        //return htmlData\n    } else {\n        console.log(&quot;Response: &quot; + response);\n        return response;\n    }\n}\n\nlet annotateHTMLsection = async (listOfCategories, enhanceTag) =&gt; {\n    let response = htmlData;\n    let document;\n\n    if (typeof window === &quot;undefined&quot;) {\n        let jsdom = await import(&quot;jsdom&quot;);\n        let { JSDOM } = jsdom;\n        let dom = new JSDOM(htmlData);\n        document = dom.window.document;\n        return annotationProcess(listOfCategories, enhanceTag, document, response);\n    } else {\n        document = window.document;\n        return annotationProcess(listOfCategories, enhanceTag, document, response);\n    }\n};\n\nlet getIPSAge = (birthDate) =&gt; {\n    let today = new Date();\n    let birthDateParsed = new Date(birthDate);\n\n    let ageMiliseconds = today - birthDateParsed;\n    let age = Math.floor(ageMiliseconds / 31536000000);\n\n    return age;\n}\n\nlet enhance = async () =&gt; {\n    //                  pregnancyCategory    breastfeedingCategory\n    //                             SNOMED    SNOMED\n    let listOfCategoriesToSearch = [&quot;W78&quot;, &quot;77386006&quot;, &quot;69840006&quot;]; //&quot;contra-indication-pregancy&quot;]\n\n    // Get IPS gender and check if is female\n    let gender;\n\n    let enhanceTag;\n\n    if (ips == &quot;&quot; || ips == null) {\n        throw new Error(&quot;Failed to load IPS: the LEE is getting a empty IPS&quot;);\n    }\n    ips.entry.forEach((element) =&gt; {\n        if (element.resource.resourceType == &quot;Patient&quot;) {\n            gender = element.resource.gender;\n            if (gender != &quot;female&quot; || getIPSAge(element.resource.birthDate) &gt;= 75) {\n                enhanceTag = &quot;collapsed&quot;;\n            } else {\n                enhanceTag = &quot;highlight&quot;;\n            }\n        }\n    });\n\n    // ePI traslation from terminology codes to their human redable translations in the sections\n    let compositions = 0;\n    let categories = [];\n    epi.entry.forEach((entry) =&gt; {\n        if (entry.resource.resourceType == &quot;Composition&quot;) {\n            compositions++;\n            //Iterated through the Condition element searching for conditions\n            entry.resource.extension.forEach((element) =&gt; {\n                \n                // Check if the position of the extension[1] is correct\n                if (element.extension[1].url == &quot;concept&quot;) {\n                    // Search through the different terminologies that may be avaible to check in the condition\n                    if (element.extension[1].valueCodeableReference.concept != undefined) {\n                        element.extension[1].valueCodeableReference.concept.coding.forEach(\n                            (coding) =&gt; {\n                                console.log(&quot;Extension: &quot; + element.extension[0].valueString + &quot;:&quot; + coding.code)\n                                // Check if the code is in the list of categories to search\n                                if (listOfCategoriesToSearch.includes(coding.code)) {\n                                    // Check if the category is already in the list of categories\n                                    categories.push(element.extension[0].valueString);\n                                }\n                            }\n                        );\n                    }\n                }\n            });\n        }\n    });\n\n    if (compositions == 0) {\n        throw new Error('Bad ePI: no category &quot;Composition&quot; found');\n    }\n\n    if (categories.length == 0) {\n        // throw new Error(&quot;No categories found&quot;, categories);\n        return htmlData;\n    }\n    //Focus (adds highlight class) the html applying every category found\n    return await annotateHTMLsection(categories, enhanceTag);\n};\n\nreturn {\n    enhance: enhance,\n    getSpecification: getSpecification,\n};\n</code></pre></div>"
  ] ; # 
  fhir:extension ( [
fhir:url [ fhir:v "http://hl7.eu/fhir/ig/gravitate-health/StructureDefinition/lee-version"^^xsd:anyURI ] ;
fhir:value [ fhir:v "dev" ]
  ] ) ; # 
  fhir:url [ fhir:v "http://hl7.eu/fhir/ig/gravitate-health/Library/mock-lib"^^xsd:anyURI] ; # 
  fhir:identifier ( [
fhir:system [ fhir:v "http://gravitate-health.lst.tfo.upm.es"^^xsd:anyURI ] ;
fhir:value [ fhir:v "pregnancy-lens" ]
  ] ) ; # 
  fhir:version [ fhir:v "0.1.0"] ; # 
  fhir:name [ fhir:v "pregnancy-lens"] ; # 
  fhir:title [ fhir:v "pregnancy-lens"] ; # 
  fhir:status [ fhir:v "draft"] ; # 
  fhir:experimental [ fhir:v "true"^^xsd:boolean] ; # 
  fhir:type [
    ( fhir:coding [
fhir:code [ fhir:v "logical-library" ]     ] )
  ] ; # 
  fhir:date [ fhir:v "2024-06-12T12:23:10.005Z"^^xsd:dateTime] ; # 
  fhir:publisher [ fhir:v "Gravitate Health Project"] ; # 
  fhir:contact ( [
fhir:name [ fhir:v "Gravitate Health Project" ] ;
    ( fhir:telecom [
fhir:system [ fhir:v "url" ] ;
fhir:value [ fhir:v "https://www.gravitatehealth.eu/" ]     ] )
  ] [
fhir:name [ fhir:v "Gravitate Health Project" ] ;
    ( fhir:telecom [
fhir:system [ fhir:v "url" ] ;
fhir:value [ fhir:v "https://www.gravitatehealth.eu/" ]     ] )
  ] ) ; # 
  fhir:description [ fhir:v "Lens that highlight or collapses pregnancy related information"] ; # 
  fhir:purpose [ fhir:v "Collapse or highlight pregnancy related information on a preprocessed ePI."] ; # 
  fhir:usage [ fhir:v "You can import this lens directly to your FHIR Server which suports Library Resource type."] ; # 
  fhir:copyright [ fhir:v "© 2024 Gravitate Health"] ; # 
  fhir:parameter ( [
fhir:use [ fhir:v "in" ] ;
fhir:documentation [ fhir:v "parameter if it exists" ] ;
fhir:type [ fhir:v "CodeableConcept" ]
  ] ) ; # 
  fhir:content ( [
fhir:contentType [ fhir:v "application/javascript" ] ;
fhir:data [ fhir:v "bGV0IHB2RGF0YSA9IHB2OwpsZXQgaHRtbERhdGEgPSBodG1sOwoKbGV0IGVwaURhdGEgPSBlcGk7CmxldCBpcHNEYXRhID0gaXBzOwoKbGV0IGdldFNwZWNpZmljYXRpb24gPSAoKSA9PiB7CiAgICByZXR1cm4gIjEuMC4wIjsKfTsKCmxldCBhbm5vdGF0aW9uUHJvY2VzcyA9IChsaXN0T2ZDYXRlZ29yaWVzLCBlbmhhbmNlVGFnLCBkb2N1bWVudCwgcmVzcG9uc2UpID0+IHsKICAgIGxpc3RPZkNhdGVnb3JpZXMuZm9yRWFjaCgoY2hlY2spID0+IHsKICAgICAgICBpZiAocmVzcG9uc2UuaW5jbHVkZXMoY2hlY2spKSB7CiAgICAgICAgICAgIGxldCBlbGVtZW50cyA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoY2hlY2spOwogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGVsZW1lbnRzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICBlbGVtZW50c1tpXS5jbGFzc0xpc3QuYWRkKGVuaGFuY2VUYWcpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgiaGVhZCIpLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJoZWFkIilbMF0ucmVtb3ZlKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJib2R5IikubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgcmVzcG9uc2UgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYm9keSIpWzBdLmlubmVySFRNTDsKICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCJSZXNwb25zZTogIiArIHJlc3BvbnNlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCJSZXNwb25zZTogIiArIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5pbm5lckhUTUwpOwogICAgICAgICAgICAgICAgcmVzcG9uc2UgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuaW5uZXJIVE1MOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7CgogICAgaWYgKHJlc3BvbnNlID09IG51bGwgfHwgcmVzcG9uc2UgPT0gIiIpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoCiAgICAgICAgICAgICJBbm5vdGF0aW9uIHByb2NjZXNzIGZhaWxlZDogUmV0dXJuZWQgZW1wdHkgb3IgbnVsbCByZXNwb25zZSIKICAgICAgICApOwogICAgICAgIC8vcmV0dXJuIGh0bWxEYXRhCiAgICB9IGVsc2UgewogICAgICAgIGNvbnNvbGUubG9nKCJSZXNwb25zZTogIiArIHJlc3BvbnNlKTsKICAgICAgICByZXR1cm4gcmVzcG9uc2U7CiAgICB9Cn0KCmxldCBhbm5vdGF0ZUhUTUxzZWN0aW9uID0gYXN5bmMgKGxpc3RPZkNhdGVnb3JpZXMsIGVuaGFuY2VUYWcpID0+IHsKICAgIGxldCByZXNwb25zZSA9IGh0bWxEYXRhOwogICAgbGV0IGRvY3VtZW50OwoKICAgIGlmICh0eXBlb2Ygd2luZG93ID09PSAidW5kZWZpbmVkIikgewogICAgICAgIGxldCBqc2RvbSA9IGF3YWl0IGltcG9ydCgianNkb20iKTsKICAgICAgICBsZXQgeyBKU0RPTSB9ID0ganNkb207CiAgICAgICAgbGV0IGRvbSA9IG5ldyBKU0RPTShodG1sRGF0YSk7CiAgICAgICAgZG9jdW1lbnQgPSBkb20ud2luZG93LmRvY3VtZW50OwogICAgICAgIHJldHVybiBhbm5vdGF0aW9uUHJvY2VzcyhsaXN0T2ZDYXRlZ29yaWVzLCBlbmhhbmNlVGFnLCBkb2N1bWVudCwgcmVzcG9uc2UpOwogICAgfSBlbHNlIHsKICAgICAgICBkb2N1bWVudCA9IHdpbmRvdy5kb2N1bWVudDsKICAgICAgICByZXR1cm4gYW5ub3RhdGlvblByb2Nlc3MobGlzdE9mQ2F0ZWdvcmllcywgZW5oYW5jZVRhZywgZG9jdW1lbnQsIHJlc3BvbnNlKTsKICAgIH0KfTsKCmxldCBnZXRJUFNBZ2UgPSAoYmlydGhEYXRlKSA9PiB7CiAgICBsZXQgdG9kYXkgPSBuZXcgRGF0ZSgpOwogICAgbGV0IGJpcnRoRGF0ZVBhcnNlZCA9IG5ldyBEYXRlKGJpcnRoRGF0ZSk7CgogICAgbGV0IGFnZU1pbGlzZWNvbmRzID0gdG9kYXkgLSBiaXJ0aERhdGVQYXJzZWQ7CiAgICBsZXQgYWdlID0gTWF0aC5mbG9vcihhZ2VNaWxpc2Vjb25kcyAvIDMxNTM2MDAwMDAwKTsKCiAgICByZXR1cm4gYWdlOwp9CgpsZXQgZW5oYW5jZSA9IGFzeW5jICgpID0+IHsKICAgIC8vICAgICAgICAgICAgICAgICAgcHJlZ25hbmN5Q2F0ZWdvcnkgICAgYnJlYXN0ZmVlZGluZ0NhdGVnb3J5CiAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05PTUVEICAgIFNOT01FRAogICAgbGV0IGxpc3RPZkNhdGVnb3JpZXNUb1NlYXJjaCA9IFsiVzc4IiwgIjc3Mzg2MDA2IiwgIjY5ODQwMDA2Il07IC8vImNvbnRyYS1pbmRpY2F0aW9uLXByZWdhbmN5Il0KCiAgICAvLyBHZXQgSVBTIGdlbmRlciBhbmQgY2hlY2sgaWYgaXMgZmVtYWxlCiAgICBsZXQgZ2VuZGVyOwoKICAgIGxldCBlbmhhbmNlVGFnOwoKICAgIGlmIChpcHMgPT0gIiIgfHwgaXBzID09IG51bGwpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIkZhaWxlZCB0byBsb2FkIElQUzogdGhlIExFRSBpcyBnZXR0aW5nIGEgZW1wdHkgSVBTIik7CiAgICB9CiAgICBpcHMuZW50cnkuZm9yRWFjaCgoZWxlbWVudCkgPT4gewogICAgICAgIGlmIChlbGVtZW50LnJlc291cmNlLnJlc291cmNlVHlwZSA9PSAiUGF0aWVudCIpIHsKICAgICAgICAgICAgZ2VuZGVyID0gZWxlbWVudC5yZXNvdXJjZS5nZW5kZXI7CiAgICAgICAgICAgIGlmIChnZW5kZXIgIT0gImZlbWFsZSIgfHwgZ2V0SVBTQWdlKGVsZW1lbnQucmVzb3VyY2UuYmlydGhEYXRlKSA+PSA3NSkgewogICAgICAgICAgICAgICAgZW5oYW5jZVRhZyA9ICJjb2xsYXBzZWQiOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZW5oYW5jZVRhZyA9ICJoaWdobGlnaHQiOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7CgogICAgLy8gZVBJIHRyYXNsYXRpb24gZnJvbSB0ZXJtaW5vbG9neSBjb2RlcyB0byB0aGVpciBodW1hbiByZWRhYmxlIHRyYW5zbGF0aW9ucyBpbiB0aGUgc2VjdGlvbnMKICAgIGxldCBjb21wb3NpdGlvbnMgPSAwOwogICAgbGV0IGNhdGVnb3JpZXMgPSBbXTsKICAgIGVwaS5lbnRyeS5mb3JFYWNoKChlbnRyeSkgPT4gewogICAgICAgIGlmIChlbnRyeS5yZXNvdXJjZS5yZXNvdXJjZVR5cGUgPT0gIkNvbXBvc2l0aW9uIikgewogICAgICAgICAgICBjb21wb3NpdGlvbnMrKzsKICAgICAgICAgICAgLy9JdGVyYXRlZCB0aHJvdWdoIHRoZSBDb25kaXRpb24gZWxlbWVudCBzZWFyY2hpbmcgZm9yIGNvbmRpdGlvbnMKICAgICAgICAgICAgZW50cnkucmVzb3VyY2UuZXh0ZW5zaW9uLmZvckVhY2goKGVsZW1lbnQpID0+IHsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIHBvc2l0aW9uIG9mIHRoZSBleHRlbnNpb25bMV0gaXMgY29ycmVjdAogICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQuZXh0ZW5zaW9uWzFdLnVybCA9PSAiY29uY2VwdCIpIHsKICAgICAgICAgICAgICAgICAgICAvLyBTZWFyY2ggdGhyb3VnaCB0aGUgZGlmZmVyZW50IHRlcm1pbm9sb2dpZXMgdGhhdCBtYXkgYmUgYXZhaWJsZSB0byBjaGVjayBpbiB0aGUgY29uZGl0aW9uCiAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQuZXh0ZW5zaW9uWzFdLnZhbHVlQ29kZWFibGVSZWZlcmVuY2UuY29uY2VwdCAhPSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5leHRlbnNpb25bMV0udmFsdWVDb2RlYWJsZVJlZmVyZW5jZS5jb25jZXB0LmNvZGluZy5mb3JFYWNoKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNvZGluZykgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCJFeHRlbnNpb246ICIgKyBlbGVtZW50LmV4dGVuc2lvblswXS52YWx1ZVN0cmluZyArICI6IiArIGNvZGluZy5jb2RlKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoZSBjb2RlIGlzIGluIHRoZSBsaXN0IG9mIGNhdGVnb3JpZXMgdG8gc2VhcmNoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxpc3RPZkNhdGVnb3JpZXNUb1NlYXJjaC5pbmNsdWRlcyhjb2RpbmcuY29kZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIGNhdGVnb3J5IGlzIGFscmVhZHkgaW4gdGhlIGxpc3Qgb2YgY2F0ZWdvcmllcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXRlZ29yaWVzLnB1c2goZWxlbWVudC5leHRlbnNpb25bMF0udmFsdWVTdHJpbmcpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgIH0pOwoKICAgIGlmIChjb21wb3NpdGlvbnMgPT0gMCkgewogICAgICAgIHRocm93IG5ldyBFcnJvcignQmFkIGVQSTogbm8gY2F0ZWdvcnkgIkNvbXBvc2l0aW9uIiBmb3VuZCcpOwogICAgfQoKICAgIGlmIChjYXRlZ29yaWVzLmxlbmd0aCA9PSAwKSB7CiAgICAgICAgLy8gdGhyb3cgbmV3IEVycm9yKCJObyBjYXRlZ29yaWVzIGZvdW5kIiwgY2F0ZWdvcmllcyk7CiAgICAgICAgcmV0dXJuIGh0bWxEYXRhOwogICAgfQogICAgLy9Gb2N1cyAoYWRkcyBoaWdobGlnaHQgY2xhc3MpIHRoZSBodG1sIGFwcGx5aW5nIGV2ZXJ5IGNhdGVnb3J5IGZvdW5kCiAgICByZXR1cm4gYXdhaXQgYW5ub3RhdGVIVE1Mc2VjdGlvbihjYXRlZ29yaWVzLCBlbmhhbmNlVGFnKTsKfTsKCnJldHVybiB7CiAgICBlbmhhbmNlOiBlbmhhbmNlLAogICAgZ2V0U3BlY2lmaWNhdGlvbjogZ2V0U3BlY2lmaWNhdGlvbiwKfTsK"^^xsd:base64Binary ]
  ] ) . #