Skip to content

About

This is a simple demo project on how to capture PROM data in REDCap and converting them into simple HL7 FHIR Questionnaire and QuestionnaireResponse formats. Both generic HL7 profiles and the MII EQ5D5L profile can be used. Implementation is based on the EQ5D5L questionnaire.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

PM4Onco PROMs

This is a simple demo project on how to capture PROM data in REDCap and converting them into simple HL7 FHIR Questionnaire and QuestionnaireResponse formats. Both generic HL7 profiles and the MII EQ5D5L profile can be used.

Implementation is based on the EQ5D5L questionnaire.

Background

PM4Onco - Personalized Medicine for (4) Oncology

This project is funded by PM4Onco.

PM4Onco aims to build a strong partnership between various organizations, including medical research groups, cancer centers, patients, and citizens. With modern technology, comprehensive data analysis, and collaboration between various fields, progress will be made to improve cancer treatment for each individual patient.

REDCap

REDCap is a secure web application for building and managing online surveys and databases. While REDCap can be used to collect virtually any type of data in any environment (including compliance with 21 CFR Part 11, FISMA, HIPAA, and GDPR), it is specifically geared to support online and offline data capture for research studies and operations.

Limitations

Note: the REDCap fields supported are currently limited to ["radio", "slider", "text", "dropdown"] but can be expanded by adjusting the two function create_fhir_questionnaire and get_redcap_prom_data. Other field types will be ignored.

The function create_eq5d5l_questionnaire_response requires a mapping from the EQ5D5L MII FHIR profile to their respective fields in the REDCap project. The current mapping is stored in fhir_to_redcap_mapping.json. Depending on your project setup you might need to change the mapping. Note: this function contains parts which are hard-coded for the EQ5D5L. Using other questionnaires should be possible, but requires some adjustments to the code structure.

Also note that there is a module dedicated to mapping REDCap fields to FHIR Resources which might be of interest: https://github.com/vanderbilt-redcap/fhir-services-module

Setup

Setting up REDCap

Create a new REDCap project and import the REDCap project configuration. By default, data capturing via email survey links and via MyCap App is supported. Participants can be added as record to the project and be sent notifications and survey links via the 'Tools for the distribution of surveys' button or can be invited to MyCap via the 'MyCap participant administration' button. For a more detailed explanation we refer to the official documentation REDCap and MyCap.

The REDCap project utilizes the ROME module which allows to annotate REDCap fields by uploading json definitions. The json definition used is the EQ5D5L MII version. For more information on the module please either inspect the demo project or refer to the official documentation.

Setting up the project

Configure a config.json file based on the provided example_config.json. For IMPORT_MODE there are two options:

  • API: you need to provide REDCAP_API_TOKEN and REDCAP_API_URL. Data and data dictionary is pulled from REDCap directly.
  • File: you need to provide FILE_PATH_REDCAP_DATA_EXPORT and FILE_PATH_REDCAP_DATA_DICT. You need to export both files from REDCap manually using the default export options (raw, comma-separated).

Depending on your implementation/setup you might need to change REDCAP_PROM_FORM_NAME and OUTPUT_PATH. If you are using the API import you need to configure an .env file based on the provided example.env.

example_config.json:

{
  "_comment": "Specify the import mode ['API', 'File'] here. For the API import mode redcap token and url have to be specified in an .env file, for file import mode the file path to the REDCap data export (FILE_PATH_REDCAP_DATA_EXPORT) and the file path to the REDCap data dictionary (FILE_PATH_REDCAP_DATA_DICT).",
  "IMPORT_MODE": "API",
  "FILE_PATH_REDCAP_DATA_EXPORT": ".../data/PM4OncoMyCapDemo_DATA_2026-06-17_1408.csv",
  "FILE_PATH_REDCAP_DATA_DICT": "../data/PM4OncoMyCapDemo_DataDictionary_2026-06-17.csv",
  "OUTPUT_PATH": "../output",
  "REDCAP_PROM_FORM_NAME": "eq5d5l"
}

example.env:

REDCAP_API_TOKEN="SOME_TOKEN"
REDCAP_API_URL="https://some-redcap-instance.de"

Creating FHIR bundles

Running the main.py creates a generic FHIR Questionnaire resource based on the REDCap data dictionary and a bundle of QuestionnaireResponse resources based on the data provided.

FHIR Questionnaire

A HL7 FHIR Questionnaire resource is generated from a REDCap data dictionary export (CSV) provided to the script. Each REDCap field becomes a Questionnaire item, and the item’s linkId is set to the REDCap field name to preserve a stable mapping back to REDCap.

Choice-based REDCap fields (dropdowns, radios) are mapped to codes in a custom CodeSystem, created from the REDCap option values and labels. This CodeSystem is stored in the Questionnaire’s contained resources and referenced from the corresponding item.answerValueSet. The base URI (or identifier) for this custom code system can be provided via the create_fhir_questionnaire function.

FHIR QuestionnaireResponse

Generic mapping solution

For the generic mapping solution (create_fhir_questionnaire), REDCap field options and display names are converted into a custom FHIR CodeSystem. This code system is built from the REDCap data dictionary and used to represent choice-based answers in the generated FHIR Questionnaire and QuestionnaireResponse resources.

Field type mappings

  • Dropdown and radio fields are mapped to coded answers in a custom CodeSystem, using an automatically generated code system identifier of the form #{field_name.replace('_', '-')}-answers.
  • Slider fields are mapped to integer answers (valueInteger) in QuestionnaireResponse.
  • Descriptive fields are represented as display-only items (type = "display") carrying the REDCap label but no answer.
  • Other REDCap field types are currently not mapped and will not appear in the generated FHIR resources.

QuestionnaireResponse structure

  • Metadata includes:

    • resourceType = "QuestionnaireResponse",
    • questionnaire (URL or identifier of the source Questionnaire),
    • status (e.g. completed),
    • subject reference (e.g. to a Patient),
    • authored timestamp.
  • Actual data are stored in the item array, where each item corresponds to a REDCap field: *linkId: the REDCap field name, used to align the response with the Questionnaire item.

    • text: the REDCap field label.
    • answer: the captured value, which is:
      • a coded answer (valueCoding) for dropdowns/radios using the custom CodeSystem,
      • an integer (valueInteger) for slider fields,
      • omitted for purely descriptive items.

MII EQ5D5L example implementation

For the EQ-5D-5L example implementation, the REDCap annotation field is used instead of a custom code system. This field is populated by the REDCap Ontologies Made Easy (ROME) external module (GitHub, Zenodo), which annotates REDCap variables with references to standard code systems and ontologies. Using these annotations, the script links REDCap choices directly to their corresponding codes in the provided code systems, ensuring that EQ-5D-5L responses are represented with standardized terminologies.

Note: The function create_eq5d5l_questionnaire_response requires a mapping from the EQ5D5L MII FHIR profile to their respective fields in the REDCap project. The current mapping is stored in fhir_to_redcap_mapping.json. Depending on your project setup you might need to change the mapping. Note: this function contains parts which are hard-coded for the EQ5D5L. Using other questionnaires should be possible, but requires some adjustments to the code structure.

ROME-based annotations

  • Each EQ-5D-5L REDCap field is annotated via ROME with:
    • a code system identifier (e.g., SNOMED CT, LOINC, or an EQ-5D-5L-specific system),
    • a concept/code for the question itself,
    • codes for each answer option matching the official EQ-5D-5L value set.
  • The mapping logic reads these annotations and uses them to populate Questionnaire.item.code and QuestionnaireResponse.item.answer.valueCoding with the appropriate system, code, and display.

Example excerpt:

@ONTOLOGY={
    "dataElement": {
        "valueCodingMap": {
            "1": {
                "coding": [{
                        "code": "MO-1",
                        "display": "Ich habe keine Probleme herumzugehen",
                        "system": "https://www.medizininformatik-initiative.de/fhir/ext/modul-pro/CodeSystem/mii-cs-pro-eq-5d-value-set"
                    }
                ]
            },
            ...
        }
    }
}

QuestionnaireResponse structure

  • The overall structure of the EQ-5D-5L QuestionnaireResponse matches the generic mapping solution:
    • standard metadata (resourceType, questionnaire, status, subject, authored),
    • response content in the item array.
  • For each annotated EQ-5D-5L field:
    • linkId holds the field name obtained by mapping the REDCap field name using the fhir_to_redcap_mapping.json,
    • text contains the original REDCap question label,
    • answer.valueCoding uses the ROME-provided code system and code.

About

This is a simple demo project on how to capture PROM data in REDCap and converting them into simple HL7 FHIR Questionnaire and QuestionnaireResponse formats. Both generic HL7 profiles and the MII EQ5D5L profile can be used. Implementation is based on the EQ5D5L questionnaire.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages