diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000000..cc34899310 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,8 @@ +{ + "name": "Synthea - synthetic patient data generator", + "build": { + "context": "..", + "dockerfile": "../Dockerfile", + "args": { "BASE_IMAGE": "mcr.microsoft.com/devcontainers/base:ubuntu", "USER": "vscode" } + } +} diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000000..6f802344a0 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,54 @@ +/.devcontainer +/.hermit + +**/.DS_Store +.classpath +.project +.settings +.gradle +/nbproject/** +/build/** + +/.gradle/ +/bin/main +/bin/test + +/failed_exports/ +/output/ +/out/ + +**/*.log + +# don't commit the autobuilt version file +src/main/resources/version.txt + +# don't commit the code maps +src/main/resources/export/condition_code_map.json +src/main/resources/export/medication_code_map.json +src/main/resources/export/drg_code_map.json +src/main/resources/export/dme_code_map.json +src/main/resources/export/hcpcs_code_map.json +src/main/resources/export/betos_code_map.json +src/main/resources/export/external_codes.csv +src/main/resources/export/snf_pdpm_code_map.json +src/main/resources/export/snf_pps_code_map.json +src/main/resources/export/snf_rev_cntr_code_map.json +src/main/resources/export/hha_rev_cntr_code_map.json +src/main/resources/export/hha_pps_case_mix_codes.csv +src/main/resources/export/hha_pps_pdgm_codes.csv +src/main/resources/export/hospice_rev_cntr_code_map.json +src/main/resources/export/inpatient_rev_cntr_code_map.json +src/main/resources/export/outpatient_rev_cntr_code_map.json + +# H2 database files +**/*.mv.db +**/*.trace.db + +# VS Code launch settings +.vscode/launch.test.json +.vscode/launch.json +.vscode/settings.json +/build/ + +# VS Code plugin files +.history diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..94f2c84702 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,29 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# Top-most EditorConfig file +root = true + +# Unix-style newlines with a newline ending every file +[*] +end_of_line = lf +insert_final_newline = true + +# Set default charset +charset = utf-8 + +[Makefile] +indent_style = tab + +# 4 space indentation (default) +indent_style = space +indent_size = 4 + +# 2 space indentation +[*.{bicep,bicepparam,html,js,jsx,ts,tsx,json,sass,yaml,yml}] +indent_size = 2 + +# Trim trailing whitespace +trim_trailing_whitespace = true + +# Max line length +max_line_length = 80 diff --git a/.gitignore b/.gitignore index a5a6574ad0..e6e8b56f20 100644 --- a/.gitignore +++ b/.gitignore @@ -5,10 +5,10 @@ .gradle /nbproject/** /build/** -bin/** /.gradle/ -/bin/ +/bin/main +/bin/test /failed_exports/ /output/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000..5ddc48da1b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,52 @@ +ARG BASE_IMAGE=ubuntu:22.04 +FROM ${BASE_IMAGE} + +ARG USER=dev + +WORKDIR /work +SHELL ["/bin/bash", "-euxo", "pipefail", "-c"] + +# setup timezone +RUN apt-get update;\ + apt-get install -yq tzdata;\ + ln -fs /usr/share/zoneinfo/America/New_York /etc/localtime;\ + dpkg-reconfigure -f noninteractive tzdata; + +# Set the locale +RUN apt-get install -yq locales; +RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && \ + locale-gen +ENV LANG en_US.UTF-8 +ENV LANGUAGE en_US:en +ENV LC_ALL en_US.UTF-8 + +# install OS deps +RUN set -eux;\ + apt-get install -y --no-install-recommends ca-certificates curl git jq make unzip zip; +RUN set -eux;\ + apt-get install -y --no-install-recommends libfreetype-dev libfreetype6 fontconfig fonts-dejavu;\ + rm -rf /var/lib/apt/lists/*; + +# run as non-root user +RUN id -u ${USER} &>/dev/null || useradd -ms /bin/bash ${USER} +USER ${USER} +WORKDIR /home/${USER}/work + +COPY --chown=${USER}:${USER} ./ ./synthea + +# install hermit and binary deps +COPY --chown=${USER}:${USER} bin/ bin/ +ENV PATH=/home/${USER}/work/bin:${PATH} +RUN set -eux;\ + hermit shell-hooks;\ + hermit install + +COPY --chown=${USER}:${USER} ./ ./synthea +RUN set -eux;\ + cd synthea;\ + make install;\ + make build; + +# Synthea repo: https://github.com/synthetichealth/synthea +# ./synthea/run_synthea -m congestive_heart_failure -c settings-chf.yml -p 10000 +# ./synthea/run_synthea -c settings-chf.yml -p 10000 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000..3f3e603a9b --- /dev/null +++ b/Makefile @@ -0,0 +1,20 @@ +.PHONY: build install visualize + +SHELL := /bin/bash + +export PATH := ./bin:${PATH} + +all: install build test visualize + +install: + hermit shell-hooks + hermit install + +build: + ./gradlew build + +test: + ./gradlew check test + +visualize: + gradle graphviz diff --git a/README.md b/README.md index e71f204fdc..f85ff298e1 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,13 @@ -# SyntheaTM Patient Generator ![Build Status](https://github.com/synthetichealth/synthea/workflows/.github/workflows/ci-build-test.yml/badge.svg?branch=master) [![codecov](https://codecov.io/gh/synthetichealth/synthea/branch/master/graph/badge.svg)](https://codecov.io/gh/synthetichealth/synthea) +# SyntheaTM Patient Generator + +![Build Status](https://github.com/synthetichealth/synthea/workflows/.github/workflows/ci-build-test.yml/badge.svg?branch=master) [![codecov](https://codecov.io/gh/synthetichealth/synthea/branch/master/graph/badge.svg)](https://codecov.io/gh/synthetichealth/synthea) [![Open in Dev Containers](https://img.shields.io/static/v1?label=Dev%20Containers&message=Open&color=blue&logo=visualstudiocode)](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/InnovaSolutions/synthea.git) SyntheaTM is a Synthetic Patient Population Simulator. The goal is to output synthetic, realistic (but not real), patient data and associated health records in a variety of formats. Read our [wiki](https://github.com/synthetichealth/synthea/wiki) and [Frequently Asked Questions](https://github.com/synthetichealth/synthea/wiki/Frequently-Asked-Questions) for more information. Currently, SyntheaTM features include: + - Birth to Death Lifecycle - Configuration-based statistics and demographics (defaults with Massachusetts Census data) - Modular Rule System @@ -30,6 +33,7 @@ These instructions are intended for those wishing to examine the Synthea source SyntheaTM requires Java JDK 11 or newer. We strongly recommend using a Long-Term Support (LTS) release of Java, 11 or 17, as issues may occur with more recent non-LTS versions. To clone the SyntheaTM repo, then build and run the test suite: + ``` git clone https://github.com/synthetichealth/synthea.git cd synthea @@ -38,28 +42,29 @@ cd synthea ### Changing the default properties - The default properties file values can be found at `src/main/resources/synthea.properties`. By default, synthea does not generate CCDA, CPCDA, CSV, or Bulk FHIR (ndjson). You'll need to -adjust this file to activate these features. See the [wiki](https://github.com/synthetichealth/synthea/wiki) +adjust this file to activate these features. See the [wiki](https://github.com/synthetichealth/synthea/wiki) for more details, or use our [guided customizer tool](https://synthetichealth.github.io/spt/#/customizer). - - ### Generate Synthetic Patients + Generating the population one at a time... + ``` ./run_synthea ``` Command-line arguments may be provided to specify a state, city, population size, or seed for randomization. + ``` run_synthea [-s seed] [-p populationSize] [state [city]] ``` Full usage info can be printed by passing the `-h` option. + ``` -$ ./run_synthea -h +$ ./run_synthea -h > Task :run Usage: run_synthea [options] [state [city]] @@ -97,13 +102,17 @@ Some settings can be changed in `./src/main/resources/synthea.properties`. SyntheaTM will output patient records in C-CDA and FHIR formats in `./output`. ### SyntheaTM GraphViz + Generate graphical visualizations of SyntheaTM rules and modules. + ``` ./gradlew graphviz ``` ### Concepts and Attributes + Generate a list of concepts (used in the records) or attributes (variables on each patient). + ``` ./gradlew concepts ./gradlew attributes diff --git a/bin/.gradle-8.3.pkg b/bin/.gradle-8.3.pkg new file mode 120000 index 0000000000..383f4511d4 --- /dev/null +++ b/bin/.gradle-8.3.pkg @@ -0,0 +1 @@ +hermit \ No newline at end of file diff --git a/bin/.openjdk@17.pkg b/bin/.openjdk@17.pkg new file mode 120000 index 0000000000..383f4511d4 --- /dev/null +++ b/bin/.openjdk@17.pkg @@ -0,0 +1 @@ +hermit \ No newline at end of file diff --git a/bin/README.hermit.md b/bin/README.hermit.md new file mode 100644 index 0000000000..e889550ba4 --- /dev/null +++ b/bin/README.hermit.md @@ -0,0 +1,7 @@ +# Hermit environment + +This is a [Hermit](https://github.com/cashapp/hermit) bin directory. + +The symlinks in this directory are managed by Hermit and will automatically +download and install Hermit itself as well as packages. These packages are +local to this environment. diff --git a/bin/activate-hermit b/bin/activate-hermit new file mode 100755 index 0000000000..fe28214d33 --- /dev/null +++ b/bin/activate-hermit @@ -0,0 +1,21 @@ +#!/bin/bash +# This file must be used with "source bin/activate-hermit" from bash or zsh. +# You cannot run it directly +# +# THIS FILE IS GENERATED; DO NOT MODIFY + +if [ "${BASH_SOURCE-}" = "$0" ]; then + echo "You must source this script: \$ source $0" >&2 + exit 33 +fi + +BIN_DIR="$(dirname "${BASH_SOURCE[0]:-${(%):-%x}}")" +if "${BIN_DIR}/hermit" noop > /dev/null; then + eval "$("${BIN_DIR}/hermit" activate "${BIN_DIR}/..")" + + if [ -n "${BASH-}" ] || [ -n "${ZSH_VERSION-}" ]; then + hash -r 2>/dev/null + fi + + echo "Hermit environment $("${HERMIT_ENV}"/bin/hermit env HERMIT_ENV) activated" +fi diff --git a/bin/gradle b/bin/gradle new file mode 120000 index 0000000000..0476496dff --- /dev/null +++ b/bin/gradle @@ -0,0 +1 @@ +.gradle-8.3.pkg \ No newline at end of file diff --git a/bin/hermit b/bin/hermit new file mode 100755 index 0000000000..7fef769248 --- /dev/null +++ b/bin/hermit @@ -0,0 +1,43 @@ +#!/bin/bash +# +# THIS FILE IS GENERATED; DO NOT MODIFY + +set -eo pipefail + +export HERMIT_USER_HOME=~ + +if [ -z "${HERMIT_STATE_DIR}" ]; then + case "$(uname -s)" in + Darwin) + export HERMIT_STATE_DIR="${HERMIT_USER_HOME}/Library/Caches/hermit" + ;; + Linux) + export HERMIT_STATE_DIR="${XDG_CACHE_HOME:-${HERMIT_USER_HOME}/.cache}/hermit" + ;; + esac +fi + +export HERMIT_DIST_URL="${HERMIT_DIST_URL:-https://github.com/cashapp/hermit/releases/download/stable}" +HERMIT_CHANNEL="$(basename "${HERMIT_DIST_URL}")" +export HERMIT_CHANNEL +export HERMIT_EXE=${HERMIT_EXE:-${HERMIT_STATE_DIR}/pkg/hermit@${HERMIT_CHANNEL}/hermit} + +if [ ! -x "${HERMIT_EXE}" ]; then + echo "Bootstrapping ${HERMIT_EXE} from ${HERMIT_DIST_URL}" 1>&2 + INSTALL_SCRIPT="$(mktemp)" + # This value must match that of the install script + INSTALL_SCRIPT_SHA256="180e997dd837f839a3072a5e2f558619b6d12555cd5452d3ab19d87720704e38" + if [ "${INSTALL_SCRIPT_SHA256}" = "BYPASS" ]; then + curl -fsSL "${HERMIT_DIST_URL}/install.sh" -o "${INSTALL_SCRIPT}" + else + # Install script is versioned by its sha256sum value + curl -fsSL "${HERMIT_DIST_URL}/install-${INSTALL_SCRIPT_SHA256}.sh" -o "${INSTALL_SCRIPT}" + # Verify install script's sha256sum + openssl dgst -sha256 "${INSTALL_SCRIPT}" | \ + awk -v EXPECTED="$INSTALL_SCRIPT_SHA256" \ + '$2!=EXPECTED {print "Install script sha256 " $2 " does not match " EXPECTED; exit 1}' + fi + /bin/bash "${INSTALL_SCRIPT}" 1>&2 +fi + +exec "${HERMIT_EXE}" --level=fatal exec "$0" -- "$@" diff --git a/bin/hermit.hcl b/bin/hermit.hcl new file mode 100644 index 0000000000..e69de29bb2 diff --git a/bin/jar b/bin/jar new file mode 120000 index 0000000000..cf7b7e07ba --- /dev/null +++ b/bin/jar @@ -0,0 +1 @@ +.openjdk@17.pkg \ No newline at end of file diff --git a/bin/jarsigner b/bin/jarsigner new file mode 120000 index 0000000000..cf7b7e07ba --- /dev/null +++ b/bin/jarsigner @@ -0,0 +1 @@ +.openjdk@17.pkg \ No newline at end of file diff --git a/bin/java b/bin/java new file mode 120000 index 0000000000..cf7b7e07ba --- /dev/null +++ b/bin/java @@ -0,0 +1 @@ +.openjdk@17.pkg \ No newline at end of file diff --git a/bin/javac b/bin/javac new file mode 120000 index 0000000000..cf7b7e07ba --- /dev/null +++ b/bin/javac @@ -0,0 +1 @@ +.openjdk@17.pkg \ No newline at end of file diff --git a/bin/javadoc b/bin/javadoc new file mode 120000 index 0000000000..cf7b7e07ba --- /dev/null +++ b/bin/javadoc @@ -0,0 +1 @@ +.openjdk@17.pkg \ No newline at end of file diff --git a/bin/javap b/bin/javap new file mode 120000 index 0000000000..cf7b7e07ba --- /dev/null +++ b/bin/javap @@ -0,0 +1 @@ +.openjdk@17.pkg \ No newline at end of file diff --git a/bin/jcmd b/bin/jcmd new file mode 120000 index 0000000000..cf7b7e07ba --- /dev/null +++ b/bin/jcmd @@ -0,0 +1 @@ +.openjdk@17.pkg \ No newline at end of file diff --git a/bin/jconsole b/bin/jconsole new file mode 120000 index 0000000000..cf7b7e07ba --- /dev/null +++ b/bin/jconsole @@ -0,0 +1 @@ +.openjdk@17.pkg \ No newline at end of file diff --git a/bin/jdb b/bin/jdb new file mode 120000 index 0000000000..cf7b7e07ba --- /dev/null +++ b/bin/jdb @@ -0,0 +1 @@ +.openjdk@17.pkg \ No newline at end of file diff --git a/bin/jdeprscan b/bin/jdeprscan new file mode 120000 index 0000000000..cf7b7e07ba --- /dev/null +++ b/bin/jdeprscan @@ -0,0 +1 @@ +.openjdk@17.pkg \ No newline at end of file diff --git a/bin/jdeps b/bin/jdeps new file mode 120000 index 0000000000..cf7b7e07ba --- /dev/null +++ b/bin/jdeps @@ -0,0 +1 @@ +.openjdk@17.pkg \ No newline at end of file diff --git a/bin/jfr b/bin/jfr new file mode 120000 index 0000000000..cf7b7e07ba --- /dev/null +++ b/bin/jfr @@ -0,0 +1 @@ +.openjdk@17.pkg \ No newline at end of file diff --git a/bin/jhsdb b/bin/jhsdb new file mode 120000 index 0000000000..cf7b7e07ba --- /dev/null +++ b/bin/jhsdb @@ -0,0 +1 @@ +.openjdk@17.pkg \ No newline at end of file diff --git a/bin/jimage b/bin/jimage new file mode 120000 index 0000000000..cf7b7e07ba --- /dev/null +++ b/bin/jimage @@ -0,0 +1 @@ +.openjdk@17.pkg \ No newline at end of file diff --git a/bin/jinfo b/bin/jinfo new file mode 120000 index 0000000000..cf7b7e07ba --- /dev/null +++ b/bin/jinfo @@ -0,0 +1 @@ +.openjdk@17.pkg \ No newline at end of file diff --git a/bin/jlink b/bin/jlink new file mode 120000 index 0000000000..cf7b7e07ba --- /dev/null +++ b/bin/jlink @@ -0,0 +1 @@ +.openjdk@17.pkg \ No newline at end of file diff --git a/bin/jmap b/bin/jmap new file mode 120000 index 0000000000..cf7b7e07ba --- /dev/null +++ b/bin/jmap @@ -0,0 +1 @@ +.openjdk@17.pkg \ No newline at end of file diff --git a/bin/jmod b/bin/jmod new file mode 120000 index 0000000000..cf7b7e07ba --- /dev/null +++ b/bin/jmod @@ -0,0 +1 @@ +.openjdk@17.pkg \ No newline at end of file diff --git a/bin/jpackage b/bin/jpackage new file mode 120000 index 0000000000..cf7b7e07ba --- /dev/null +++ b/bin/jpackage @@ -0,0 +1 @@ +.openjdk@17.pkg \ No newline at end of file diff --git a/bin/jps b/bin/jps new file mode 120000 index 0000000000..cf7b7e07ba --- /dev/null +++ b/bin/jps @@ -0,0 +1 @@ +.openjdk@17.pkg \ No newline at end of file diff --git a/bin/jrunscript b/bin/jrunscript new file mode 120000 index 0000000000..cf7b7e07ba --- /dev/null +++ b/bin/jrunscript @@ -0,0 +1 @@ +.openjdk@17.pkg \ No newline at end of file diff --git a/bin/jshell b/bin/jshell new file mode 120000 index 0000000000..cf7b7e07ba --- /dev/null +++ b/bin/jshell @@ -0,0 +1 @@ +.openjdk@17.pkg \ No newline at end of file diff --git a/bin/jstack b/bin/jstack new file mode 120000 index 0000000000..cf7b7e07ba --- /dev/null +++ b/bin/jstack @@ -0,0 +1 @@ +.openjdk@17.pkg \ No newline at end of file diff --git a/bin/jstat b/bin/jstat new file mode 120000 index 0000000000..cf7b7e07ba --- /dev/null +++ b/bin/jstat @@ -0,0 +1 @@ +.openjdk@17.pkg \ No newline at end of file diff --git a/bin/jstatd b/bin/jstatd new file mode 120000 index 0000000000..cf7b7e07ba --- /dev/null +++ b/bin/jstatd @@ -0,0 +1 @@ +.openjdk@17.pkg \ No newline at end of file diff --git a/bin/keytool b/bin/keytool new file mode 120000 index 0000000000..cf7b7e07ba --- /dev/null +++ b/bin/keytool @@ -0,0 +1 @@ +.openjdk@17.pkg \ No newline at end of file diff --git a/bin/rmiregistry b/bin/rmiregistry new file mode 120000 index 0000000000..cf7b7e07ba --- /dev/null +++ b/bin/rmiregistry @@ -0,0 +1 @@ +.openjdk@17.pkg \ No newline at end of file diff --git a/bin/serialver b/bin/serialver new file mode 120000 index 0000000000..cf7b7e07ba --- /dev/null +++ b/bin/serialver @@ -0,0 +1 @@ +.openjdk@17.pkg \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000000..5995e9e181 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,6 @@ +version: "3" +services: + synthea: + build: . + tty: true + stdin_open: true diff --git a/src/test/java/org/mitre/synthea/export/CCDAExporterTest.java b/src/test/java/org/mitre/synthea/export/CCDAExporterTest.java index 49afd49817..8f11e15cc7 100644 --- a/src/test/java/org/mitre/synthea/export/CCDAExporterTest.java +++ b/src/test/java/org/mitre/synthea/export/CCDAExporterTest.java @@ -39,7 +39,7 @@ /** * This is a rudimentary check of the CCDA Export. It uses XPath expressions to ensure that the * mandatory sections for the Continuity of Care Document (CCD) (V3) are present as specified in - * HL7 Implementation Guide for CDA® Release 2: Consolidated CDA Templates for Clinical Notes + * HL7 Implementation Guide for CDA(R) Release 2: Consolidated CDA Templates for Clinical Notes * Specification Version: 2.1.0.7 September 2022. */ public class CCDAExporterTest { @@ -192,4 +192,4 @@ public void testFailedCCDAExports() throws Exception { System.out.println("Done."); } -} \ No newline at end of file +} diff --git a/src/test/java/org/mitre/synthea/modules/calculators/FraminghamTest.java b/src/test/java/org/mitre/synthea/modules/calculators/FraminghamTest.java index 32a4ee9e74..d19f281f74 100644 --- a/src/test/java/org/mitre/synthea/modules/calculators/FraminghamTest.java +++ b/src/test/java/org/mitre/synthea/modules/calculators/FraminghamTest.java @@ -55,7 +55,7 @@ public void testCvdModelPatient2() { Risk Factor Value Points Age 53 8 Total cholesterol 161 1 - HDL 55 −1 + HDL 55 -1 Nontreated SBP N/A 0 Treated SBP 125 2 Smoker No 0