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