Code Monkey home page Code Monkey logo

cda2fhir's Introduction

cda2fhir License Info

cda2fhir is a Java library to transform HL7 CDA R2 instances to HL7 FHIR resources. More specifically, cda2fhir enables automatic transformation of Consolidated CDA (C-CDA) Release 2.1 compliant document instances to the corresponding FHIR DSTU2 resources, wherever possible implementing the U.S. Data Access Framework (DAF) FHIR Implementation Guide. For this purpose, cda2fhir provides extensible document transformers, resource transformers, data type transformers and value set transformers. The current implementation provides a document transformer for Continuity of Care Document (CCD), but further document transformers, e.g. for Discharge Summary or Referral Note, can be easily introduced by reusing the already existing section and entry transformers. Although the cda2fhir library expects C-CDA R2.1 compliant documents/entries, it has been tested as well with several older document instances compliant with earlier releases of C-CDA. The official HL7 FHIR Validator is also integrated for automated validation of the generated FHIR resources.

All the mappings implemented between CDA artifacts and FHIR resources, data types and value sets are documented in this sheet: C-CDA CCD to FHIR DAF Mapping

Model Driven Health Tools (MDHT) is used for CDA manipulation and HAPI is used for FHIR manipulation. The current implementation produces DSTU2 resources. We are planning to cover STU3 resources as well, after the specification becomes official.

Installation

Apache Maven is required to build cda2fhir. Please visit http://maven.apache.org/ in order to install Maven on your system.

Under the root directory of the cda2fhir project run the following:

$ cda2fhir> mvn install

In order to make a clean install run the following:

$ cda2fhir> mvn clean install

These will build the cda2fhir library and also run a number of test cases, which will transform some C-CDA Continuity of Care Document (CCD) instances, and some manually crafted CDA artifacts (e.g. entry class instances) and datatype instances to corresponding FHIR resources, wherever possible using the DAF profile.

Transforming a CDA document to a Bundle of corresponding FHIR resources

// Load MDHT CDA packages. Otherwise ContinuityOfCareDocument and similar documents will not be recognised.
// This has to be called before loading the document; otherwise will have no effect.
CDAUtil.loadPackages();

// Read a Continuity of Care Document (CCD) instance, which is the official sample CCD instance
// distributed with C-CDA 2.1 specs, with a few extensions for having a more complete document
FileInputStream fis = new FileInputStream("src/test/resources/C-CDA_R2-1_CCD.xml");
ClinicalDocument cda = CDAUtil.load(fis);

// Init an object of CCDTransformerImpl class, which implements the generic ICDATransformer interface.
// FHIR resource id generator can be either an incremental counter, or a UUID generator.
// The default is UUID; here it is set as COUNTER.
ICDATransformer ccdTransformer = new CCDTransformerImpl(IdGeneratorEnum.COUNTER);

// By default, FHIR DSTU2 resources are generated by setting the appropriate DAF profile URLs
// in meta.profile attribute of resources. This is configurable through the statically (i.e. globally)
// managed Config class, and can be turned on or off.
Config.setGenerateDafProfileMetadata(true);

// By default, html formatted narratives are generated in text.div attributes of FHIR DSTU2 resources,
// thanks to the automated narrative generation capability of HAPI that is enabled via thymeleaf library.
// This is configurable through the statically managed Config class, and can be turned on or off.
Config.setGenerateNarrative(true);

// Finally, the CCD document instance is transformed to a FHIR Bundle, where the first entry is
// the Composition corresponding to the ClinicalDocument, and further entries are the ones referenced
// from the Composition.
Bundle bundle = ccdTransformer.transformDocument(cda);

// Through HAPI library, the Bundle can easily be printed in JSON or XML format.
FHIRUtil.printJSON(bundle, "src/test/resources/output/C-CDA_R2-1_CCD-w-daf.json");

Further code examples can be found in CCDTransformerTest class. The outcome of the above transformation operation for the CCD instance available in the C-CDA 2.1 specification is available here: https://github.com/srdc/cda2fhir/blob/master/src/test/resources/C-CDA_R2-1_CCD-w-daf.json

Transforming a CDA artifact (e.g. an entry class) to the corresponding FHIR resource(s)

// Init an object of ResourceTransformerImpl class, which implements the IResourceTransformer
// interface. When instantiated separately from the CDATransformer context, FHIR resources are
// generated with UUID ids, and a default patient reference is added as "Patient/0"
IResourceTransformer resTransformer = new ResourceTransformerImpl();

// Configuration of DAF profile URL creation in meta.profile and narrative generation in text.div is
// again configurable through the statically managed Config class.
Config.setGenerateDafProfileMetadata(true);
Config.setGenerateNarrative(false);

// Assume we already have a CCD instance in the ccd object below (skipping CDA artifact creation from scratch)
// Traverse all the sections of the CCD instance
for(Section cdaSec: ccd.getSections()) {
    // Transform a CDA section to a FHIR Composition.Section backbone resource
    Composition.Section fhirSec = resTransformer.tSection2Section(cdaSec);

    // if a CDA section is instance of a Family History Section (as identified through its templateId)
    if(cdaSec instanceof FamilyHistorySection) {
        // cast the section to FamilyHistorySection
        FamilyHistorySection famSec = (FamilyHistorySection) cdaSec;
        // traverse the Family History Organizers within the Family History Section
        for(FamilyHistoryOrganizer fhOrganizer : famSec.getFamilyHistories()) {
            // Transform each C-CDA FamilyHistoryOrganizer instance to FHIR (DAF) FamilyMemberHistory instance
            FamilyMemberHistory fmh = resTransformer.tFamilyHistoryOrganizer2FamilyMemberHistory(fhOrganizer);
        }
    }
}

// Again, any FHIR resource can be printed through FHIRUtil methods.
FHIRUtil.printXML(fmh, "src/test/resources/output/family-member-history.xml");

It should be noted that most of the time, IResourceTransformer methods return a FHIR Bundle composed of a few FHIR resources, instead of a single FHIR resource as in the example above. For example, tProblemObservation2Condition method returns a Bundle that contains the corresponding Condition as the first entry, which can also include other referenced resources such as Encounter, Practitioner.

Further examples can be found in ResourceTransformerTest class and CCDTransformerImpl class.

Validating generated FHIR resources

We have also integrated the official HL7 FHIR Validator, although in a bit ugly way since this validator is not available in any Maven repo. We have implemented a wrapper interface and a class on top of this validator: IValidator and ValidatorImpl. A resource can be validated individually, or a Bundle containing several resources as in the case of CDA transformation outcome can be validated at once. When (DAF) profile metadata is provided within the resources' meta.profile attribute, validation takes into account this profile as well. Validation outcome is provided as HTML within an OutputStream.

// Init an object of ValidatorImpl class, which implements the IValidator interface.
IValidator validator = new ValidatorImpl();

// Assume we already have a Bundle object to be validated at hand. Call the validateBundle method
// of the validator and get the validation outcome as HTML in a ByteArrayOutputStream.
ByteArrayOutputStream valOutcomeOs = (ByteArrayOutputStream) validator.validateBundle(bundle);

// The HTML can be printed to a file.
FileOutputStream fos = new FileOutputStream(new File("src/test/resources/output/validation-result-w-profile-for-C-CDA_R2-1_CCD.html"));
valOutcomeOs.writeTo(fos);

// Close the streams
valOutcomeOs.close();
fos.close();

Further examples can be found in ValidatorTest class. Some of the tests in this class are ignored, as validating takes some time, especially due to external Terminology Server access dependency. But they do work, users can enable them.

Unfortunately it is not easy to find up and running DSTU2 terminology servers all the time, hence this test can fail when none of the terminology servers configured in Config is accessible. In this case, if you happen to know an accessible DSTU2 terminology server, you can either update Config or set via the setTerminologyServer method of the validator. If you cannot find a running terminology server, then you can just ignore the validator tests.

Acknowledgement

This research has received funding from the European Union’s Horizon 2020 research and innovation programme under grant agreement No 689181, C3-Cloud Project (A Federated Collaborative Care Cure Cloud Architecture for Addressing the Needs of Multi-morbidity and Managing Poly-pharmacy).

This research has received funding from the European Union’s Horizon 2020 research and innovation programme under grant agreement No 689444, POWER2DM Project (Predictive model-based decision support for diabetes patient empowerment).

cda2fhir's People

Contributors

ismailkocdemir avatar mbaskaya avatar msfyuksel avatar necipfazil avatar rmharrison avatar tahsinkose avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cda2fhir's Issues

Server not respondoing

The server provided in the validation test does not respond, you may want to enhance your documentation to reflect that and what changes are appropriate to pass this validation test.

Code in client program just like CCDTransformerTest giving ClassCast error

Good day.
Thank you for your hard work on this project. I'm hoping it will help me.
I work for a Michigan HIE, and I'm trying to put together a self-service project so
providers, insurers, etc., can convert their CCDs to FHIR format.
I downloaded your project, built it, and the tests ran fine.

I tried to take three of the methods that convert CCDs to FHIR from your test, and
put them into a command-line-runnable client using the same methods (renamed).
I copied the pom.xml and I believe I have the same repo jar versions as the original.

I first tried setting up the client as it's own project, and including the jar created from
the build of srdc/cda2fhir. I put the validator jar in the project lib dir also,
and I am able to get it to run where it executes the three methods, but for each
method, I'm getting:

15:05:05.074 [org.mihin.ccda2fhir.clients.CCD2JsonClient.main()] ERROR
t.c.s.c.t.CCDTransformerImpl - ClinicalDocument could not be cast to
ContinuityOfCareDocument. Returning null
java.lang.ClassCastException: org.openhealthtools.mdht.uml.cda.impl.
ClinicalDocumentImpl cannot be cast to org.openhealthtools.mdht.uml.cda.
consol.ContinuityOfCareDocument
at tr.com.srdc.cda2fhir.transform.CCDTransformerImpl.transformDocument(CCDTransformerImpl.java:150)
at org.mihin.ccda2fhir.clients.CCD2JsonClient.runReferenceCCDInstance(CCD2JsonClient.java:121)
at org.mihin.ccda2fhir.clients.CCD2JsonClient.execute(CCD2JsonClient.java:93)
at org.mihin.ccda2fhir.clients.CCD2JsonClient.main(CCD2JsonClient.java:60)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:297)
at java.lang.Thread.run(Thread.java:748)

The line in my client this occurs at is apparently the FHIRUtil.printJSON(bundle, "");
call, but the line numbers only match the second and third methods, not the first.
I've cleaned and re-built the project a fiew times, but I still get the above.

I could send the class file and a log of the run, but there is no place to submit them.
I can email them if you'd like. Text only.

Thank you again.

Reverse FHIR to CDA transformation

Hello,
in a prototype i am developing I need to transform my fhir resources to CDA docs in order to interoperate with a old system which just supports this interoperability standard.

do you guys think we could use this project to develop the other fhir2cda conversion?

Regards

multithreading issue

Anyone has done CCD to FHIR conversion in multithreads? I try CCDTransformerTest code in multiple threads, and see MDHT throws exceptions randomly.

Thanks,
aj

Just a few quick questions

I successfully installed the CDA2FHIR.

But, I did not see anywhere, in any documentation, where we started any kind of service.

The installation went very well, and quite smoothly.

But, when starting or stopping the server itself, are there any specific processes that need to be stopped or started?

I do not see any instructions for starting or stopping services of any kind.

Quick install question

I am relatively new to Maven, and I am not 100% certain of the answer here:

In your documentation, you state to run the following commands:

mvn install

mvn clean install

Do I need to run both commands, or just one of them?

I am assuming if it is just one, that "mvn install" would be acceptable for the very first installation attempt.

I am assuming if this is a secondary, or repeat install, that I would want to run the "mvn clean install".

Am I correct in my assumption?

If yes, can you tweak the wording to indicate one or the other?

Thanks in advance.

fresh mvn clean install fails

It appears there is an issue with the default configuration for this project. If you do a fresh clone, and try mvn clean install there will be errors.

The issue appears to be in ValidatorTest.java:158. The bundle will most likely never equal null. Instead changing this line to:
if(bundle != null && bundle.getId().getIdPartAsLong() != null ) {
appears to work.

Also for the project to build without issue the Config.java should also have "http://ontoserver.csiro.au/stu3-latest/" added to VALIDATOR_TERMINOLOGY_SERVER_URLS.

Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.19.1:test

failed tests when we type mvn clean install
testString2DateTime(tr.com.srdc.cda2fhir.DataTypesTransformerTest) Time elapsed: 0.007 sec <<< FAILURE!
org.junit.ComparisonFailure: TS.value was not transformed expected:<2016-05-27T15:[4]0:00+08:00> but was:<2016-05-27T15:[1]0:00+08:00>
at tr.com.srdc.cda2fhir.DataTypesTransformerTest.testString2DateTime(DataTypesTransformerTest.java:654)

testTS2DateTime(tr.com.srdc.cda2fhir.DataTypesTransformerTest) Time elapsed: 0.001 sec <<< FAILURE!
org.junit.ComparisonFailure: TS.value was not transformed expected:<2016-05-27T15:[4]0:00+08:00> but was:<2016-05-27T15:[1]0:00+08:00>
at tr.com.srdc.cda2fhir.DataTypesTransformerTest.testTS2DateTime(DataTypesTransformerTest.java:789)

Results :

Failed tests:
DataTypesTransformerTest.testString2DateTime:654 TS.value was not transformed expected:<2016-05-27T15:[4]0:00+08:00> but was:<2016-05-27T15:[1]0:00+08:00>
DataTypesTransformerTest.testTS2DateTime:789 TS.value was not transformed expected:<2016-05-27T15:[4]0:00+08:00> but was:<2016-05-27T15:[1]0:00+08:00>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.