# HL7 CDA template implementation to OpenEHR OPT **Category:** [Implementation](https://discourse.openehr.org/c/implem/39) **Created:** 2023-02-15 18:35 UTC **Views:** 749 **Replies:** 15 **URL:** https://discourse.openehr.org/t/hl7-cda-template-implementation-to-openehr-opt/3579 --- ## Post #1 by @ISys Hi everyone. So this is my first post here, so please bear in mind that I may not know all the posts yet in this topic. I have a qustion regarding the polish HL7 CDA implementation of e.g. clinial document as OpenEHR file. The case is that, I am trying to remap Clinical document (like: https://www.cez.gov.pl/HL7POL-1.3.2/plcda-html-1.3.2/plcda-html/tmp-2.16.840.1.113883.3.4424.13.10.1.18-2020-06-08T000000.html ) into template with proper archetypes. Could you give me any advice on that, I mean - how those values could look like in archetype designer? Thanks. --- ## Post #2 by @ian.mcnicoll This is a template that mirrors the International Patient Summary not a CDR Discharge but should give a clue about what are some of the content detail archetypes you might want to use. https://ckm.openehr.org/ckm/templates/1013.26.376 Remember too that the openEHR Composition class which is at the root of the template carries quite a few attributes that are targets for CDR attributes e.g CDA:Author -> Composition/composer --- ## Post #3 by @pablo Hi, in general CDA entries have one archetype each, and could be mapped to openEHR entries, structures or clusters, depending on the specific CDA concept. Since CDA has 3 levels, depends on which level of CDA you have, how to better map it to an openEHR COMPOSITION (a ClinicalDocument in CDA is the equivalent of COMPOSITION in openEHR). Level 1 is CDA with non structured body, CDA level 2 is structured body with sections, and level 3 with entries and codes. In general a good mapping to openEHR is CDA level 3, which is the one that is more structured. Level 2 has sections with narrative text, and level 1 if for something like a PDF in the CDA. Another thing you will find is the CDA header contains demographic data, which in an openEHR COMPOSITION you might not have, because the demographic data is linked to the EHR, and the EHR concept in CDA doesn't exist. So in general what is on the CDA recordTarget is really an entry on an MPI and a reference from an openEHR EHR to that entry. That doesn't mean you can't put (technically) demographics in the COMPOSITION, is just that it's not a good practice. I've been working with both standards for a while and mapping is not so simple. Hope that helps. --- ## Post #4 by @ISys Thank you for that Ian and Pablo. In terms of the practical approach, could you give me advice on mapping constans? I mean...if there are slots in HL7 CDA PL like typeId (extension: POCD_HD000040 and root: 2.16.840.1.113883.1.3), then what kind of objects they are as archetypes in templates? Sorry for such basic questions, but I am very new in those EHR/HL7/FHIR standards. --- ## Post #5 by @ian.mcnicoll Hi, I'll lash up a very simple partial composition template to give you an idea of the approach. Ian --- ## Post #6 by @ISys Thank you! --- ## Post #7 by @ian.mcnicoll This is just a rough first cut based on the example data at https://www.cez.gov.pl/HL7POL-1.3.2/plcda-html-1.3.2/plcda-html/tmp-2.16.840.1.113883.3.4424.13.10.1.18-2020-06-08T000000.html As others have said, the patient details are out of scope and many of the Level 1 details are captured by openEHR Composition attributes that do not show in the Archetype Designer. See https://specifications.openehr.org/releases/UML/latest/index.html#Architecture___18_1_83e026d_1433773264376_574143_6873 e,g Composer is equivalent to CDA Author [Read-only view](https://tools.openehr.org/designer/#/viewer/shared/Pz9zaGFyZWRJZD0xJDdmNWI4MmJjMDZjOTRiNmE5NjdkZWE1NjNjYWQ3NDhm) [Link to a Template Fileset that can be imported into Archetype Designer.](https://www.dropbox.com/s/4pirb25jyklqqoj/PL%20-%20CDA%20-%20Discharge%20Summary%20%281%29.zip?dl=0t) And finally Structured format Json example of an openEHR composition that matches the template. ```json { "pl_-_cda_-_discharge_summary": { "_uid": [ "37fd5e9a-ce9f-4998-9ba5-da61643f992e::example::1" ], "context": [ { "xds_metadata": [ { "author_specialty": [ "Author specialty 64" ], "class_code": [ "Class code 53" ], "document_type": [ "Document type 51" ], "confidentiality_code": [ "Confidentiality code 75" ], "health_care_facility_type": [ "Health care facility type 59" ], "practice_setting_code": [ "Practice setting code 40" ], "event_code": [ "Event code 97" ], } ], "start_time": [ "2023-02-17T16:59:23.367Z" ], "setting": [ { "|code": "238", "|value": "other care", "|terminology": "openehr" } ] } ], "encounters": [ { "encounter": [ { "encounter_date": [ "2023-02-17T16:59:23.367Z" ], "category": [ "Category 71" ], "event_type": [ "Event type 23" ], "note": [ "Note 37" ], "language": [ { "|code": "en", "|terminology": "ISO_639-1" } ], "encoding": [ { "|code": "UTF-8", "|terminology": "IANA_character-sets" } ] } ] } ], "diagnosis": [ { "primary_diagnosis": [ { "primary_diagnosis": [ "Primary diagnosis 17" ], "details": [ { "diagnostic_category": [ { "|code": "at0064", "|value": "Principal diagnosis", "|terminology": "local" } ] } ], "language": [ { "|code": "en", "|terminology": "ISO_639-1" } ], "encoding": [ { "|code": "UTF-8", "|terminology": "IANA_character-sets" } ] } ], "secondary_diagnosis": [ "secondary_diagnosis": [ "Secondary diagnosis 61" ], "details": [ { "diagnostic_category": [ { "|code": "at0066", "|value": "Secondary diagnosis", "|terminology": "local" } ] } ], "language": [ { "|code": "en", "|terminology": "ISO_639-1" } ], "encoding": [ { "|code": "UTF-8", "|terminology": "IANA_character-sets" } ] } ] } ], "relevant_diagnostic_tests_laboratory_data": [ { "research_results": [ { "any_event": [ { "test_name": [ "Reported results" ], "media_file": [ { "content": [ { "": "http://med.tube.com/sample", "|mediatype": "text/html", } ], "time": [ "2023-02-17T16:59:23.37Z" ] } ], "language": [ { "|code": "en", "|terminology": "ISO_639-1" } ], "encoding": [ { "|code": "UTF-8", "|terminology": "IANA_character-sets" } ] } ] } ], "pharmacotherapy_and_physical_rehabilitation": [ { "epicrisis": [ { "synopsis": [ "Synopsis 78" ], "language": [ { "|code": "en", "|terminology": "ISO_639-1" } ], "encoding": [ { "|code": "UTF-8", "|terminology": "IANA_character-sets" } ] } ] } ], "prescriptions": [ { "recommendation": [ { "recommendation": [ "Recommendation 63" ], "language": [ { "|code": "en", "|terminology": "ISO_639-1" } ], "encoding": [ { "|code": "UTF-8", "|terminology": "IANA_character-sets" } ] } ], "medication_statement": [ { "any_event": [ { "manufactured_labelled_drug": [ "Manufactured labelled drug 69" ], "time": [ "2023-02-17T17:04:26.799Z" ] } ], "language": [ { "|code": "en", "|terminology": "ISO_639-1" } ], "encoding": [ { "|code": "UTF-8", "|terminology": "IANA_character-sets" } ] } ] } ], "category": [ { "|code": "433", "|value": "event", "|terminology": "openehr" } ], "language": [ { "|code": "en", "|terminology": "ISO_639-1" } ], "territory": [ { "|code": "US", "|terminology": "ISO_3166-1" } ] } } ``` --- ## Post #8 by @pablo If I recall correctly this POCD_HD000040 is saying "this is a CDA in HL7 V3". If you need to map codes values, that would be the CD and other coded values in HL7 data types, that should be mapped to openEHR DV_CODED_TEXT. But the important thing besides mapping data points is to map clinical concepts. For instance, when you read the implementation guide of the CDAs you need to map, check which clinical concepts are there and find the corresponding openEHR archetypes to map to. --- ## Post #9 by @ISys Wow, thank you so much Ian, thank helped very much! Pablo, my biggest concern was about coding constant values e.g. extension/root. Also, I need to dig more into Archetype Designer, as I had some trouble with generating the template from https://toolkit.cabolabs.com/ because there wasn't any content in sample canonical json instance. --- ## Post #10 by @ian.mcnicoll Remember that any TEXT or CODED_TEXT datatype can carry multiple code mappings, which includes putting mappings e.g to a CDA Section on the name/value attribute of an openEHR Section, as the name attribute (drawn from the LOCATABLE class is a DV_TEXT. https://specifications.openehr.org/releases/UML/latest/index.html#Architecture___18_1_83e026d_1433773264832_882590_7967 The only question is why and when you would want to do that. CDA is completely dependent on using external terminologies to label parts of the record. whereas openEHR uses archetype_node_id's to do the same. Practically this could be in STRUCTURED format ``` "diagnosis": [ { " _name/value/_mapping" :[ { "|match": "=", "target|terminology": "LOINC", "target|code": "29548-5", } ], } ], "primary_diagnosis": [ "_name/value/_mapping" : [ { "|match": "=", "target|terminology": "SNOMED CT", "target|code": "8319008", } ], { ``` I may not have those structures exactly correct but you'll get the idea! In canonical XML ```xml Diagnosis = LOINC 29548-5 openEHR-EHR-SECTION.adhoc.v1 1.0.4 ``` --- ## Post #11 by @ISys Thank you Ian for additional information. Now I have another question regarding submitting composition in flat format. As I have webtemplate, I can check the values to submit (please see on the attachment) [WebTemp.json|attachment](upload://nborthrLMytzRSj20etsNdMBqBv.json) (56.8 KB) Also, the OPT file: [PL_CDA_DischargeSummary.opt|attachment](upload://2GJA1shmhVkJCpCclRf3Yl2weXu.opt) (85.9 KB) But regardless on value that I submit: ``` { "ctx/language": "en", "pl_cda_dischargesummary/composer|name": "en", "ctx/territory": "GB", "pl_cda_dischargesummary/context/cd_metadata/classcode|code": "DOCCLIN", "pl_cda_dischargesummary/context/cd_metadata/classcode|value": "classCode" } ``` my response is like: ``` "/context/other_context[at0001]/items[openEHR-EHR-CLUSTER.cd_metadata.v1]/items[at0030]: Attribute has 0 occurrences, but must be 1..1... ``` How could proper flat json submission look like for defined values like classcode? Thank you --- ## Post #12 by @pablo [quote="ISys, post:9, topic:3579"] Pablo, my biggest concern was about coding constant values e.g. extension/root. [/quote] In some cases that is mapped to DV_CODED_TEXT, in other cases those could be UID_BASED_ID in openEHR. There is no magic there, you need to map code by code by it's meaning. [quote="ISys, post:9, topic:3579"] I had some trouble with generating the template from https://toolkit.cabolabs.com/ because there wasn’t any content in sample canonical json instance. [/quote] The openEHR Toolkit doesn't generate templates, you need to provide an operational template (OPT) and it will generate valid openEHR COMPOSITION instances based on the constraints of the OPT. Can you publish the OPT you tested with? (I'm the creator of the openEHR Toolkit and might be able to help you there) --- ## Post #13 by @ian.mcnicoll 1. What CDR are you using and which API call? 2. Can you upload your example composition. ``` "pl_cda_dischargesummary/context/cd_metadata/classcode|code": "DOCCLIN", "pl_cda_dischargesummary/context/cd_metadata/classcode|value": "classCode" ``` If you are sending CodedText you need to supply the teminologyID ``` "pl_cda_dischargesummary/context/cd_metadata/classcode|code": "DOCCLIN", "pl_cda_dischargesummary/context/cd_metadata/classcode|value": "classCode" "pl_cda_dischargesummary/context/cd_metadata/classcode|terminology": "LOINC" ``` --- ## Post #14 by @ISys Dear Pablo, Here you have the OPT file: [PL_CDA_DischargeSummary (1).opt|attachment](upload://5tYUprKlUfd4hRZI2ws2JXRNvHK.opt) (142.2 KB) Actually I came up with an idea how to do API request (sample below): ``` { "ctx/language": "en", "pl_cda_dischargesummary/composer|name": "en", "ctx/territory": "GB", "pl_cda_dischargesummary/context/cd_metadata/classcode": "DOCCLIN", "pl_cda_dischargesummary/context/cd_metadata/id/root": "EVN", "pl_cda_dischargesummary/context/cd_metadata/id/extension": "DOCCLIN", "pl_cda_dischargesummary/context/cd_metadata/title": "DOCCLIN", "pl_cda_dischargesummary/context/cd_metadata/effectivetime": "2020-06-08T17:04:30.621Z", "pl_cda_dischargesummary/context/cd_metadata/confidentiality_code/code": "A", "pl_cda_dischargesummary/context/cd_metadata/confidentiality_code/codesystem": "2.16.840.1.113883.5.25", "pl_cda_dischargesummary/context/cd_metadata/languagecode": "test", "pl_cda_dischargesummary/context/cd_metadata/setid/root": "test", "pl_cda_dischargesummary/context/cd_metadata/setid/extension": "test", "pl_cda_dischargesummary/context/cd_metadata/versionnumber": "test" } ``` For now I have no other issues regarding making the requests, only to provide detailed template. On that topic, I've encountered a problem - for the internal/external coded text - is there possibility to provide csv list of objects? I have a few hundreds values for race: [https://www.cez.gov.pl/HL7POL-1.3.1.2/plcda-1.3.1.2/plcda-html-1.3.1.2/plcda-html-1.3.1.2/voc-2.16.840.1.113883.1.11.14914-2014-03-26T000000.html](https://www.cez.gov.pl/HL7POL-1.3.1.2/plcda-1.3.1.2/plcda-html-1.3.1.2/plcda-html-1.3.1.2/voc-2.16.840.1.113883.1.11.14914-2014-03-26T000000.html) and filling the table by hand could take pretty long... --- ## Post #15 by @birger.haarbrandt Is there maybe a terminology service available with a FHIR API? Depending on your openEHR server, there is direct support for external value sets (EHRbase and Better Platform support this for example). You can find some examples for the correct binding within templates like here: https://ckm.highmed.org/ckm/templates/1246.169.1200 The CKM resolves the reference against a central FHIR-Terminology Server instance. Edit: the documentation for EHRbase may give you some better idea how to use it (https://ehrbase.readthedocs.io/en/latest/08_terminology_validation/index.html) --- ## Post #16 by @ISys Thank you Birger for that. I have found the option for changing the terminology server and there is most of that what I need. About the uploading composition, I have some issue. On the picture below there is structure of my template (from archetype): ![Screenshot from 2023-02-28 18-09-38|453x500](upload://pUVe1mgEilZ5nrsp9Yss4xwPy4U.png) But when I am trying to upload the comp. there is an error for name object. Part of my flat json is: ``` "pl_cda_dischargesummary/plcdabaserecordtarget/dane_pacjenta/recordtarget/patient/name/given:0": "PSN" ``` And this is the error that I have: ``` Could not consume Parts [pl_cda_dischargesummary/plcdabaserecordtarget/dane_pacjenta/recordtarget/patient/name/given:0] ``` I know that for objects with cardinality ` 0..*/1...*` (as id and name) I must give an index in there, but it is not working anyway. As an attachment I send the OPT file. [PL_CDA_DischargeSummary.opt|attachment](upload://vhhdzUaCTeIRyRTvRtXKZL9f4cC.opt) (232.7 KB) However, for id it is working (as below): ``` "pl_cda_dischargesummary/plcdabaserecordtarget/dane_pacjenta/recordtarget/id:0/root": "2.16.840.1.113883.3.4424.1.1.616", "pl_cda_dischargesummary/plcdabaserecordtarget/dane_pacjenta/recordtarget/id:0/extension": "fsdf", ``` Is there anything that I am missing something there? Thank you --- **Canonical:** https://discourse.openehr.org/t/hl7-cda-template-implementation-to-openehr-opt/3579 **Original content:** https://discourse.openehr.org/t/hl7-cda-template-implementation-to-openehr-opt/3579