Trying to fix basic functionality again.

This commit is contained in:
2025-03-23 11:53:47 -07:00
parent ebda48190a
commit 2141e81f42
406 changed files with 173963 additions and 69 deletions

6
.env Normal file
View File

@@ -0,0 +1,6 @@
# Anthropic API Key for Claude
ANTHROPIC_API_KEY=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
# Optional: Customize these settings
# SYNTHEA_MODULES_DIR=./src/main/resources/modules
# SYNTHEA_OUTPUT_DIR=./output

6
.env.example Normal file
View File

@@ -0,0 +1,6 @@
# Anthropic API Key for Claude
ANTHROPIC_API_KEY=your_api_key_here
# Optional: Customize these settings
# SYNTHEA_MODULES_DIR=./src/main/resources/modules
# SYNTHEA_OUTPUT_DIR=./output

504
.nextflow.log Normal file
View File

@@ -0,0 +1,504 @@
Mar-23 11:46:18.059 [main] DEBUG nextflow.cli.Launcher - $> nextflow run main.nf --disease_name 'Multiple Sclerosis' --population 10
Mar-23 11:46:18.328 [main] DEBUG nextflow.cli.CmdRun - N E X T F L O W ~ version 24.10.5
Mar-23 11:46:18.401 [main] DEBUG nextflow.plugin.PluginsFacade - Setting up plugin manager > mode=prod; embedded=false; plugins-dir=/Users/richman/.nextflow/plugins; core-plugins: nf-amazon@2.9.2,nf-azure@1.10.2,nf-cloudcache@0.4.2,nf-codecommit@0.2.2,nf-console@1.1.4,nf-google@1.15.4,nf-tower@1.9.3,nf-wave@1.7.4
Mar-23 11:46:18.445 [main] INFO o.pf4j.DefaultPluginStatusProvider - Enabled plugins: []
Mar-23 11:46:18.446 [main] INFO o.pf4j.DefaultPluginStatusProvider - Disabled plugins: []
Mar-23 11:46:18.455 [main] INFO org.pf4j.DefaultPluginManager - PF4J version 3.12.0 in 'deployment' mode
Mar-23 11:46:18.502 [main] INFO org.pf4j.AbstractPluginManager - No plugins
Mar-23 11:46:18.606 [main] DEBUG nextflow.config.ConfigBuilder - Found config local: /Users/richman/workspace/synthea-alldiseases/nextflow.config
Mar-23 11:46:18.618 [main] DEBUG nextflow.config.ConfigBuilder - Parsing config file: /Users/richman/workspace/synthea-alldiseases/nextflow.config
Mar-23 11:46:18.773 [main] DEBUG n.secret.LocalSecretsProvider - Secrets store: /Users/richman/.nextflow/secrets/store.json
Mar-23 11:46:18.784 [main] DEBUG nextflow.secret.SecretsLoader - Discovered secrets providers: [nextflow.secret.LocalSecretsProvider@22df874e] - activable => nextflow.secret.LocalSecretsProvider@22df874e
Mar-23 11:46:18.865 [main] DEBUG nextflow.config.ConfigBuilder - Applying config profile: `standard`
Mar-23 11:46:20.661 [main] DEBUG nextflow.cli.CmdRun - Applied DSL=2 from script declaration
Mar-23 11:46:20.698 [main] DEBUG nextflow.cli.CmdRun - Launching `main.nf` [astonishing_jennings] DSL2 - revision: eefd540325
Mar-23 11:46:20.702 [main] DEBUG nextflow.plugin.PluginsFacade - Plugins default=[]
Mar-23 11:46:20.702 [main] DEBUG nextflow.plugin.PluginsFacade - Plugins resolved requirement=[]
Mar-23 11:46:20.820 [main] DEBUG nextflow.Session - Session UUID: 02e2b57f-ce09-4ca9-9884-4a04f4cc41f5
Mar-23 11:46:20.823 [main] DEBUG nextflow.Session - Run name: astonishing_jennings
Mar-23 11:46:20.826 [main] DEBUG nextflow.Session - Executor pool size: 10
Mar-23 11:46:20.840 [main] DEBUG nextflow.file.FilePorter - File porter settings maxRetries=3; maxTransfers=50; pollTimeout=null
Mar-23 11:46:20.852 [main] DEBUG nextflow.util.ThreadPoolBuilder - Creating thread pool 'FileTransfer' minSize=10; maxSize=30; workQueue=LinkedBlockingQueue[-1]; allowCoreThreadTimeout=false
Mar-23 11:46:20.910 [main] DEBUG nextflow.cli.CmdRun -
Version: 24.10.5 build 5935
Created: 04-03-2025 17:55 UTC (09:55 PDT)
System: Mac OS X 10.16
Runtime: Groovy 4.0.23 on OpenJDK 64-Bit Server VM 15.0.2+7-27
Encoding: UTF-8 (UTF-8)
Process: 74324@MacBookPro.localdomain [192.168.1.157]
CPUs: 10 - Mem: 32 GB (19.2 MB) - Swap: 6 GB (1.6 GB)
Mar-23 11:46:20.942 [main] DEBUG nextflow.Session - Work-dir: /Users/richman/workspace/synthea-alldiseases/work [Mac OS X]
Mar-23 11:46:20.943 [main] DEBUG nextflow.Session - Script base path does not exist or is not a directory: /Users/richman/workspace/synthea-alldiseases/bin
Mar-23 11:46:20.958 [main] DEBUG nextflow.executor.ExecutorFactory - Extension executors providers=[]
Mar-23 11:46:20.973 [main] DEBUG nextflow.Session - Observer factory: DefaultObserverFactory
Mar-23 11:46:21.062 [main] DEBUG nextflow.cache.CacheFactory - Using Nextflow cache factory: nextflow.cache.DefaultCacheFactory
Mar-23 11:46:21.105 [main] DEBUG nextflow.util.CustomThreadPool - Creating default thread pool > poolSize: 11; maxThreads: 1000
Mar-23 11:46:21.179 [main] DEBUG nextflow.Session - Session start
Mar-23 11:46:21.188 [main] DEBUG nextflow.trace.TraceFileObserver - Workflow started -- trace file: /Users/richman/workspace/synthea-alldiseases/trace.txt
Mar-23 11:46:22.257 [main] DEBUG nextflow.script.ScriptRunner - > Launching execution
Mar-23 11:46:22.496 [main] DEBUG nextflow.executor.ExecutorFactory - << taskConfig executor: local
Mar-23 11:46:22.496 [main] DEBUG nextflow.executor.ExecutorFactory - >> processorType: 'local'
Mar-23 11:46:22.512 [main] DEBUG nextflow.executor.Executor - [warm up] executor > local
Mar-23 11:46:22.519 [main] DEBUG n.processor.LocalPollingMonitor - Creating local task monitor for executor 'local' > cpus=10; memory=32 GB; capacity=10; pollInterval=100ms; dumpInterval=5m
Mar-23 11:46:22.522 [main] DEBUG n.processor.TaskPollingMonitor - >>> barrier register (monitor: local)
Mar-23 11:46:22.691 [main] DEBUG nextflow.executor.ExecutorFactory - << taskConfig executor: local
Mar-23 11:46:22.691 [main] DEBUG nextflow.executor.ExecutorFactory - >> processorType: 'local'
Mar-23 11:46:22.699 [main] DEBUG nextflow.Session - Workflow process names [dsl2]: checkAndGetModule, generatePatients
Mar-23 11:46:22.701 [main] DEBUG nextflow.Session - Igniting dataflow network (2)
Mar-23 11:46:22.701 [main] DEBUG nextflow.processor.TaskProcessor - Starting process > checkAndGetModule
Mar-23 11:46:22.702 [main] DEBUG nextflow.processor.TaskProcessor - Starting process > generatePatients
Mar-23 11:46:22.703 [main] DEBUG nextflow.script.ScriptRunner - Parsed script files:
Script_90804d0522a60a16: /Users/richman/workspace/synthea-alldiseases/main.nf
Mar-23 11:46:22.704 [main] DEBUG nextflow.script.ScriptRunner - > Awaiting termination
Mar-23 11:46:22.704 [main] DEBUG nextflow.Session - Session await
Mar-23 11:46:23.175 [Task submitter] DEBUG n.executor.local.LocalTaskHandler - Launch cmd line: /bin/bash -ue .command.run
Mar-23 11:46:23.181 [Task submitter] INFO nextflow.Session - [48/6b3902] Submitted process > checkAndGetModule
Mar-23 11:46:24.277 [Task monitor] DEBUG n.processor.TaskPollingMonitor - Task completed > TaskHandler[id: 1; name: checkAndGetModule; status: COMPLETED; exit: 1; error: -; workDir: /Users/richman/workspace/synthea-alldiseases/work/48/6b39028ef9836c1989643d36911af1]
Mar-23 11:46:24.279 [Task monitor] DEBUG nextflow.util.ThreadPoolBuilder - Creating thread pool 'TaskFinalizer' minSize=10; maxSize=30; workQueue=LinkedBlockingQueue[-1]; allowCoreThreadTimeout=false
Mar-23 11:46:24.301 [TaskFinalizer-1] DEBUG nextflow.processor.TaskProcessor - Handling unexpected condition for
task: name=checkAndGetModule; work-dir=/Users/richman/workspace/synthea-alldiseases/work/48/6b39028ef9836c1989643d36911af1
error [nextflow.exception.ProcessFailedException]: Process `checkAndGetModule` terminated with an error exit status (1)
Mar-23 11:46:24.343 [TaskFinalizer-1] ERROR nextflow.processor.TaskProcessor - Error executing process > 'checkAndGetModule'
Caused by:
Process `checkAndGetModule` terminated with an error exit status (1)
Command executed:
echo "Looking for module at /app/src/main/resources/modules/multiple_sclerosis.json"
if [ -f "/app/src/main/resources/modules/multiple_sclerosis.json" ]; then
echo "Module exists, copying..."
cp "/app/src/main/resources/modules/multiple_sclerosis.json" .
else
echo "Module not found, generating..."
python3 /app/module_generator/module_generator.py --disease "Multiple Sclerosis" --output "multiple_sclerosis.json"
if [ -f "multiple_sclerosis.json" ]; then
echo "Successfully generated module"
else
echo "Error: Failed to generate module"
exit 1
fi
fi
Command exit status:
1
Command output:
Looking for module at /app/src/main/resources/modules/multiple_sclerosis.json
Module not found, generating...
Command error:
Looking for module at /app/src/main/resources/modules/multiple_sclerosis.json
Module not found, generating...
Traceback (most recent call last):
File "/app/module_generator/module_generator.py", line 90, in <module>
client = anthropic.Client(api_key=api_key)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/venv/lib/python3.12/site-packages/anthropic/_client.py", line 113, in __init__
super().__init__(
File "/opt/venv/lib/python3.12/site-packages/anthropic/_base_client.py", line 758, in __init__
self._client = http_client or SyncHttpxClientWrapper(
^^^^^^^^^^^^^^^^^^^^^^^
TypeError: Client.__init__() got an unexpected keyword argument 'proxies'
Work dir:
/Users/richman/workspace/synthea-alldiseases/work/48/6b39028ef9836c1989643d36911af1
Container:
synthea-module-generator
Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line
Mar-23 11:46:24.361 [main] DEBUG nextflow.Session - Session await > all processes finished
Mar-23 11:46:24.361 [TaskFinalizer-1] DEBUG nextflow.Session - Session aborted -- Cause: Process `checkAndGetModule` terminated with an error exit status (1)
Mar-23 11:46:24.396 [Task monitor] DEBUG n.processor.TaskPollingMonitor - <<< barrier arrives (monitor: local) - terminating tasks monitor poll loop
Mar-23 11:46:24.397 [main] DEBUG nextflow.Session - Session await > all barriers passed
Mar-23 11:46:24.431 [main] DEBUG n.trace.WorkflowStatsObserver - Workflow completed > WorkflowStats[succeededCount=0; failedCount=1; ignoredCount=0; cachedCount=0; pendingCount=0; submittedCount=0; runningCount=0; retriesCount=0; abortedCount=0; succeedDuration=0ms; failedDuration=995ms; cachedDuration=0ms;loadCpus=0; loadMemory=0; peakRunning=1; peakCpus=1; peakMemory=0; ]
Mar-23 11:46:24.437 [main] DEBUG nextflow.trace.TraceFileObserver - Workflow completed -- saving trace file
Mar-23 11:46:24.466 [TaskFinalizer-1] DEBUG nextflow.Session -
Thread[Actor Thread 5,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)
java.base@15.0.2/java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:920)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1056)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Reference Handler,10,system]
java.base@15.0.2/java.lang.ref.Reference.waitForReferencePendingList(Native Method)
java.base@15.0.2/java.lang.ref.Reference.processPendingReferences(Reference.java:241)
java.base@15.0.2/java.lang.ref.Reference$ReferenceHandler.run(Reference.java:213)
Thread[Actor Thread 4,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)
java.base@15.0.2/java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:920)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1056)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Finalizer,8,system]
java.base@15.0.2/java.lang.Object.wait(Native Method)
java.base@15.0.2/java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:155)
java.base@15.0.2/java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:176)
java.base@15.0.2/java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:170)
Thread[Actor Thread 2,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)
java.base@15.0.2/java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:920)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1056)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Common-Cleaner,8,InnocuousThreadGroup]
java.base@15.0.2/java.lang.Object.wait(Native Method)
java.base@15.0.2/java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:155)
java.base@15.0.2/jdk.internal.ref.CleanerImpl.run(CleanerImpl.java:148)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
java.base@15.0.2/jdk.internal.misc.InnocuousThread.run(InnocuousThread.java:134)
Thread[Actor Thread 8,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)
java.base@15.0.2/java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:920)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1056)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Actor Thread 11,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)
java.base@15.0.2/java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:920)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1056)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[process reaper,10,system]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:252)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:462)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)
java.base@15.0.2/java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:937)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1055)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Actor Thread 3,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)
java.base@15.0.2/java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:920)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1056)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Actor Thread 6,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)
java.base@15.0.2/java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:920)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1056)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Actor Thread 1,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)
java.base@15.0.2/java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:920)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1056)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Signal Dispatcher,9,system]
Thread[Thread-1,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:252)
java.base@15.0.2/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:1661)
java.base@15.0.2/java.util.concurrent.LinkedBlockingDeque.pollFirst(LinkedBlockingDeque.java:515)
java.base@15.0.2/java.util.concurrent.LinkedBlockingDeque.poll(LinkedBlockingDeque.java:677)
app//nextflow.util.SimpleAgent.run(SimpleAgent.groovy:89)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
java.base@15.0.2/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.base@15.0.2/java.lang.reflect.Method.invoke(Method.java:564)
app//org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343)
app//groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:328)
app//groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1333)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
app//groovy.lang.MetaClassImpl.invokeMethodClosure(MetaClassImpl.java:1017)
app//groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1207)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1007)
app//groovy.lang.Closure.call(Closure.java:433)
app//groovy.lang.Closure.call(Closure.java:412)
app//groovy.lang.Closure.run(Closure.java:505)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Actor Thread 7,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)
java.base@15.0.2/java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:920)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1056)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[TaskFinalizer-1,5,main]
java.base@15.0.2/java.lang.Thread.dumpThreads(Native Method)
java.base@15.0.2/java.lang.Thread.getAllStackTraces(Thread.java:1649)
app//nextflow.util.SysHelper.dumpThreads(SysHelper.groovy:188)
app//nextflow.Session.abort(Session.groovy:800)
app//nextflow.Session.fault(Session.groovy:766)
app//nextflow.processor.TaskPollingMonitor.finalizeTask(TaskPollingMonitor.groovy:695)
app//nextflow.processor.TaskPollingMonitor.safeFinalizeTask(TaskPollingMonitor.groovy:678)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
java.base@15.0.2/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.base@15.0.2/java.lang.reflect.Method.invoke(Method.java:564)
app//org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343)
app//groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:328)
app//groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1333)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1007)
app//org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:645)
app//org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:628)
app//org.codehaus.groovy.runtime.InvokerHelper.invokeMethodSafe(InvokerHelper.java:82)
app//nextflow.processor.TaskPollingMonitor$_checkTaskStatus_lambda8.doCall(TaskPollingMonitor.groovy:668)
app//nextflow.processor.TaskPollingMonitor$$Lambda$437/0x0000000800f54530.run(Unknown Source)
java.base@15.0.2/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
java.base@15.0.2/java.util.concurrent.FutureTask.run(FutureTask.java:264)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[pool-2-thread-1,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:341)
java.base@15.0.2/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:505)
java.base@15.0.2/java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3137)
java.base@15.0.2/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1614)
java.base@15.0.2/java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:435)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1056)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[AnsiLogObserver,5,main]
java.base@15.0.2/java.lang.Object.wait(Native Method)
app//nextflow.trace.AnsiLogObserver.render0(AnsiLogObserver.groovy:185)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
java.base@15.0.2/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.base@15.0.2/java.lang.reflect.Method.invoke(Method.java:564)
app//org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343)
app//groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:328)
app//groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1333)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
app//groovy.lang.MetaClassImpl.invokeMethodClosure(MetaClassImpl.java:1017)
app//groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1207)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1007)
app//groovy.lang.Closure.call(Closure.java:433)
app//groovy.lang.Closure.call(Closure.java:412)
app//groovy.lang.Closure.run(Closure.java:505)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Task submitter,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:341)
java.base@15.0.2/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:505)
java.base@15.0.2/java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3137)
java.base@15.0.2/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1614)
app//nextflow.processor.TaskPollingMonitor.awaitTasks(TaskPollingMonitor.groovy:388)
app//nextflow.processor.TaskPollingMonitor.submitLoop(TaskPollingMonitor.groovy:412)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
java.base@15.0.2/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.base@15.0.2/java.lang.reflect.Method.invoke(Method.java:564)
app//org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343)
app//groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:328)
app//groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1333)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
app//groovy.lang.MetaClassImpl.invokeMethodClosure(MetaClassImpl.java:1017)
app//groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1207)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1007)
app//groovy.lang.Closure.call(Closure.java:433)
app//groovy.lang.Closure.call(Closure.java:412)
app//groovy.lang.Closure.run(Closure.java:505)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Actor Thread 10,5,main]
java.base@15.0.2/java.util.zip.Inflater.inflateBytesBytes(Native Method)
java.base@15.0.2/java.util.zip.Inflater.inflate(Inflater.java:378)
java.base@15.0.2/java.util.zip.InflaterInputStream.read(InflaterInputStream.java:152)
java.base@15.0.2/jdk.internal.loader.Resource.getBytes(Resource.java:126)
java.base@15.0.2/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:822)
java.base@15.0.2/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:723)
java.base@15.0.2/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:646)
java.base@15.0.2/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:604)
java.base@15.0.2/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:168)
java.base@15.0.2/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
app//de.javakaffee.kryoserializers.UnmodifiableCollectionsSerializer.registerSerializers(UnmodifiableCollectionsSerializer.java:193)
java.base@15.0.2/java.lang.invoke.LambdaForm$DMH/0x0000000800bb9840.invokeStaticInit(LambdaForm$DMH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800f8b040.invoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c0ec40.guardWithCatch(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c0e440.reinvoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c0d840.guard(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c0e440.reinvoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c0d840.guard(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c0e440.reinvoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c89c40.invoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c0a440.invokeExact_MT(LambdaForm$MH)
app//org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache(IndyInterface.java:321)
java.base@15.0.2/java.lang.invoke.LambdaForm$DMH/0x0000000800bdd440.invokeStatic(LambdaForm$DMH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c0f440.invoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.Invokers$Holder.linkToCallSite(Invokers$Holder)
app//nextflow.util.KryoHelper.newInstance(SerializationHelper.groovy:91)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
java.base@15.0.2/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.base@15.0.2/java.lang.reflect.Method.invoke(Method.java:564)
app//org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343)
app//groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:328)
app//groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1586)
app//org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:611)
app//org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:182)
app//nextflow.util.KryoHelper$1.methodMissing(SerializationHelper.groovy)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
java.base@15.0.2/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.base@15.0.2/java.lang.reflect.Method.invoke(Method.java:564)
app//org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343)
app//groovy.lang.MetaClassImpl.invokeMissingMethod(MetaClassImpl.java:924)
app//groovy.lang.MetaClassImpl.invokePropertyOrMissing(MetaClassImpl.java:1413)
app//groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1335)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1007)
java.base@15.0.2/java.lang.invoke.LambdaForm$DMH/0x0000000800bff440.invokeInterface(LambdaForm$DMH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c9f840.invoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800cac040.invoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c2ac40.guardWithCatch(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfbc40.reinvoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfc040.guard(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfbc40.reinvoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfc040.guard(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfbc40.reinvoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c2dc40.invoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c0a440.invokeExact_MT(LambdaForm$MH)
app//org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache(IndyInterface.java:321)
java.base@15.0.2/java.lang.invoke.LambdaForm$DMH/0x0000000800bdd440.invokeStatic(LambdaForm$DMH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfa440.invoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.Invokers$Holder.linkToCallSite(Invokers$Holder)
app//nextflow.util.KryoHelper$1.initialValue(SerializationHelper.groovy:60)
app//nextflow.util.KryoHelper$1.initialValue(SerializationHelper.groovy)
java.base@15.0.2/java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:195)
java.base@15.0.2/java.lang.ThreadLocal.get(ThreadLocal.java:172)
java.base@15.0.2/java.lang.invoke.DirectMethodHandle$Holder.invokeVirtual(DirectMethodHandle$Holder)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c2ac40.guardWithCatch(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfbc40.reinvoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfc040.guard(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfbc40.reinvoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfc040.guard(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfbc40.reinvoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c2dc40.invoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c0a440.invokeExact_MT(LambdaForm$MH)
app//org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache(IndyInterface.java:321)
java.base@15.0.2/java.lang.invoke.LambdaForm$DMH/0x0000000800bdd440.invokeStatic(LambdaForm$DMH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfa440.invoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.Invokers$Holder.linkToCallSite(Invokers$Holder)
app//nextflow.util.KryoHelper.kryo(SerializationHelper.groovy:79)
java.base@15.0.2/java.lang.invoke.LambdaForm$DMH/0x0000000800b8fc40.invokeStatic(LambdaForm$DMH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c2b440.invoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c2ac40.guardWithCatch(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfbc40.reinvoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfc040.guard(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfbc40.reinvoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c2dc40.invoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c0a440.invokeExact_MT(LambdaForm$MH)
app//org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache(IndyInterface.java:321)
java.base@15.0.2/java.lang.invoke.LambdaForm$DMH/0x0000000800bdd440.invokeStatic(LambdaForm$DMH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfa440.invoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.Invokers$Holder.linkToCallSite(Invokers$Holder)
app//nextflow.util.KryoHelper.serialize(SerializationHelper.groovy:166)
app//nextflow.trace.TraceRecord.serialize(TraceRecord.groovy:573)
app//nextflow.cache.CacheDB.writeTaskEntry0(CacheDB.groovy:147)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
java.base@15.0.2/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.base@15.0.2/java.lang.reflect.Method.invoke(Method.java:564)
app//org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343)
app//groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:328)
app//groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1333)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1007)
app//org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:645)
app//org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:628)
app//org.codehaus.groovy.runtime.InvokerHelper.invokeMethodSafe(InvokerHelper.java:82)
app//nextflow.cache.CacheDB$_putTaskAsync_closure1.doCall(CacheDB.groovy:157)
app//nextflow.cache.CacheDB$_putTaskAsync_closure1.call(CacheDB.groovy)
app//groovyx.gpars.agent.AgentBase.onMessage(AgentBase.java:102)
app//groovyx.gpars.agent.Agent.handleMessage(Agent.java:84)
app//groovyx.gpars.agent.AgentCore$1.handleMessage(AgentCore.java:48)
app//groovyx.gpars.util.AsyncMessagingCore.run(AsyncMessagingCore.java:132)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[main,5,main]
java.base@15.0.2/java.lang.Object.wait(Native Method)
java.base@15.0.2/java.lang.Thread.join(Thread.java:1303)
java.base@15.0.2/java.lang.Thread.join(Thread.java:1371)
app//nextflow.trace.AnsiLogObserver.onFlowComplete(AnsiLogObserver.groovy:506)
app//nextflow.Session.notifyFlowComplete(Session.groovy:1155)
app//nextflow.Session.shutdown0(Session.groovy:749)
app//nextflow.Session.destroy(Session.groovy:694)
app//nextflow.script.ScriptRunner.shutdown(ScriptRunner.groovy:260)
app//nextflow.script.ScriptRunner.execute(ScriptRunner.groovy:146)
app//nextflow.cli.CmdRun.run(CmdRun.groovy:376)
app//nextflow.cli.Launcher.run(Launcher.groovy:503)
app//nextflow.cli.Launcher.main(Launcher.groovy:658)
Thread[Notification Thread,9,system]
Thread[Actor Thread 9,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)
java.base@15.0.2/java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:920)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1056)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Mar-23 11:46:24.470 [TaskFinalizer-1] WARN nextflow.util.SimpleAgent - Got an interrupted exception while taking agent result | java.lang.InterruptedException
Mar-23 11:46:24.658 [main] DEBUG nextflow.cache.CacheDB - Closing CacheDB done
Mar-23 11:46:24.685 [main] DEBUG nextflow.script.ScriptRunner - > Execution complete -- Goodbye

511
.nextflow.log.1 Normal file
View File

@@ -0,0 +1,511 @@
Mar-23 11:44:25.724 [main] DEBUG nextflow.cli.Launcher - $> nextflow run main.nf --disease_name 'Multiple Sclerosis' --population 10
Mar-23 11:44:26.022 [main] DEBUG nextflow.cli.CmdRun - N E X T F L O W ~ version 24.10.5
Mar-23 11:44:26.079 [main] DEBUG nextflow.plugin.PluginsFacade - Setting up plugin manager > mode=prod; embedded=false; plugins-dir=/Users/richman/.nextflow/plugins; core-plugins: nf-amazon@2.9.2,nf-azure@1.10.2,nf-cloudcache@0.4.2,nf-codecommit@0.2.2,nf-console@1.1.4,nf-google@1.15.4,nf-tower@1.9.3,nf-wave@1.7.4
Mar-23 11:44:26.129 [main] INFO o.pf4j.DefaultPluginStatusProvider - Enabled plugins: []
Mar-23 11:44:26.130 [main] INFO o.pf4j.DefaultPluginStatusProvider - Disabled plugins: []
Mar-23 11:44:26.138 [main] INFO org.pf4j.DefaultPluginManager - PF4J version 3.12.0 in 'deployment' mode
Mar-23 11:44:26.192 [main] INFO org.pf4j.AbstractPluginManager - No plugins
Mar-23 11:44:26.303 [main] DEBUG nextflow.config.ConfigBuilder - Found config local: /Users/richman/workspace/synthea-alldiseases/nextflow.config
Mar-23 11:44:26.317 [main] DEBUG nextflow.config.ConfigBuilder - Parsing config file: /Users/richman/workspace/synthea-alldiseases/nextflow.config
Mar-23 11:44:26.466 [main] DEBUG n.secret.LocalSecretsProvider - Secrets store: /Users/richman/.nextflow/secrets/store.json
Mar-23 11:44:26.474 [main] DEBUG nextflow.secret.SecretsLoader - Discovered secrets providers: [nextflow.secret.LocalSecretsProvider@c827db] - activable => nextflow.secret.LocalSecretsProvider@c827db
Mar-23 11:44:26.570 [main] DEBUG nextflow.config.ConfigBuilder - Applying config profile: `standard`
Mar-23 11:44:28.572 [main] DEBUG nextflow.cli.CmdRun - Applied DSL=2 from script declaration
Mar-23 11:44:28.598 [main] DEBUG nextflow.cli.CmdRun - Launching `main.nf` [distracted_curran] DSL2 - revision: ab2562e4a1
Mar-23 11:44:28.602 [main] DEBUG nextflow.plugin.PluginsFacade - Plugins default=[]
Mar-23 11:44:28.603 [main] DEBUG nextflow.plugin.PluginsFacade - Plugins resolved requirement=[]
Mar-23 11:44:28.705 [main] DEBUG nextflow.Session - Session UUID: ae62d0f9-dec1-462d-a18a-b4b9ebf0f702
Mar-23 11:44:28.706 [main] DEBUG nextflow.Session - Run name: distracted_curran
Mar-23 11:44:28.708 [main] DEBUG nextflow.Session - Executor pool size: 10
Mar-23 11:44:28.723 [main] DEBUG nextflow.file.FilePorter - File porter settings maxRetries=3; maxTransfers=50; pollTimeout=null
Mar-23 11:44:28.742 [main] DEBUG nextflow.util.ThreadPoolBuilder - Creating thread pool 'FileTransfer' minSize=10; maxSize=30; workQueue=LinkedBlockingQueue[-1]; allowCoreThreadTimeout=false
Mar-23 11:44:28.958 [main] DEBUG nextflow.cli.CmdRun -
Version: 24.10.5 build 5935
Created: 04-03-2025 17:55 UTC (09:55 PDT)
System: Mac OS X 10.16
Runtime: Groovy 4.0.23 on OpenJDK 64-Bit Server VM 15.0.2+7-27
Encoding: UTF-8 (UTF-8)
Process: 73685@MacBookPro.localdomain [192.168.1.157]
CPUs: 10 - Mem: 32 GB (18.5 MB) - Swap: 6 GB (1.6 GB)
Mar-23 11:44:29.023 [main] DEBUG nextflow.Session - Work-dir: /Users/richman/workspace/synthea-alldiseases/work [Mac OS X]
Mar-23 11:44:29.024 [main] DEBUG nextflow.Session - Script base path does not exist or is not a directory: /Users/richman/workspace/synthea-alldiseases/bin
Mar-23 11:44:29.044 [main] DEBUG nextflow.executor.ExecutorFactory - Extension executors providers=[]
Mar-23 11:44:29.060 [main] DEBUG nextflow.Session - Observer factory: DefaultObserverFactory
Mar-23 11:44:29.129 [main] DEBUG nextflow.cache.CacheFactory - Using Nextflow cache factory: nextflow.cache.DefaultCacheFactory
Mar-23 11:44:29.162 [main] DEBUG nextflow.util.CustomThreadPool - Creating default thread pool > poolSize: 11; maxThreads: 1000
Mar-23 11:44:29.230 [main] DEBUG nextflow.Session - Session start
Mar-23 11:44:29.237 [main] DEBUG nextflow.trace.TraceFileObserver - Workflow started -- trace file: /Users/richman/workspace/synthea-alldiseases/trace.txt
Mar-23 11:44:30.406 [main] DEBUG nextflow.script.ScriptRunner - > Launching execution
Mar-23 11:44:30.757 [main] DEBUG nextflow.executor.ExecutorFactory - << taskConfig executor: local
Mar-23 11:44:30.758 [main] DEBUG nextflow.executor.ExecutorFactory - >> processorType: 'local'
Mar-23 11:44:30.786 [main] DEBUG nextflow.executor.Executor - [warm up] executor > local
Mar-23 11:44:30.795 [main] DEBUG n.processor.LocalPollingMonitor - Creating local task monitor for executor 'local' > cpus=10; memory=32 GB; capacity=10; pollInterval=100ms; dumpInterval=5m
Mar-23 11:44:30.801 [main] DEBUG n.processor.TaskPollingMonitor - >>> barrier register (monitor: local)
Mar-23 11:44:30.992 [main] DEBUG nextflow.executor.ExecutorFactory - << taskConfig executor: local
Mar-23 11:44:30.993 [main] DEBUG nextflow.executor.ExecutorFactory - >> processorType: 'local'
Mar-23 11:44:31.002 [main] DEBUG nextflow.Session - Workflow process names [dsl2]: checkAndGetModule, generatePatients
Mar-23 11:44:31.004 [main] DEBUG nextflow.Session - Igniting dataflow network (2)
Mar-23 11:44:31.005 [main] DEBUG nextflow.processor.TaskProcessor - Starting process > checkAndGetModule
Mar-23 11:44:31.005 [main] DEBUG nextflow.processor.TaskProcessor - Starting process > generatePatients
Mar-23 11:44:31.007 [main] DEBUG nextflow.script.ScriptRunner - Parsed script files:
Script_b4244dfae6385692: /Users/richman/workspace/synthea-alldiseases/main.nf
Mar-23 11:44:31.008 [main] DEBUG nextflow.script.ScriptRunner - > Awaiting termination
Mar-23 11:44:31.010 [main] DEBUG nextflow.Session - Session await
Mar-23 11:44:31.414 [Task submitter] DEBUG n.executor.local.LocalTaskHandler - Launch cmd line: /bin/bash -ue .command.run
Mar-23 11:44:31.419 [Task submitter] INFO nextflow.Session - [5f/61e0a1] Submitted process > checkAndGetModule
Mar-23 11:44:32.587 [Task monitor] DEBUG n.processor.TaskPollingMonitor - Task completed > TaskHandler[id: 1; name: checkAndGetModule; status: COMPLETED; exit: 1; error: -; workDir: /Users/richman/workspace/synthea-alldiseases/work/5f/61e0a106b3bf7b6d8599a7220c029c]
Mar-23 11:44:32.591 [Task monitor] DEBUG nextflow.util.ThreadPoolBuilder - Creating thread pool 'TaskFinalizer' minSize=10; maxSize=30; workQueue=LinkedBlockingQueue[-1]; allowCoreThreadTimeout=false
Mar-23 11:44:32.609 [SIGINT handler] DEBUG nextflow.Session - Session aborted -- Cause: SIGINT
Mar-23 11:44:32.610 [TaskFinalizer-1] DEBUG nextflow.processor.TaskProcessor - Handling unexpected condition for
task: name=checkAndGetModule; work-dir=/Users/richman/workspace/synthea-alldiseases/work/5f/61e0a106b3bf7b6d8599a7220c029c
error [nextflow.exception.ProcessFailedException]: Process `checkAndGetModule` terminated with an error exit status (1)
Mar-23 11:44:32.634 [main] DEBUG nextflow.Session - Session await > all processes finished
Mar-23 11:44:32.696 [SIGINT handler] DEBUG nextflow.Session -
Thread[process reaper,10,system]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:252)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:462)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)
java.base@15.0.2/java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:937)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1055)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[pool-2-thread-1,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:341)
java.base@15.0.2/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:505)
java.base@15.0.2/java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3137)
java.base@15.0.2/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1614)
java.base@15.0.2/java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:435)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1056)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Task submitter,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:341)
java.base@15.0.2/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:505)
java.base@15.0.2/java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3137)
java.base@15.0.2/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1614)
app//nextflow.processor.TaskPollingMonitor.awaitTasks(TaskPollingMonitor.groovy:388)
app//nextflow.processor.TaskPollingMonitor.submitLoop(TaskPollingMonitor.groovy:412)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
java.base@15.0.2/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.base@15.0.2/java.lang.reflect.Method.invoke(Method.java:564)
app//org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343)
app//groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:328)
app//groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1333)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
app//groovy.lang.MetaClassImpl.invokeMethodClosure(MetaClassImpl.java:1017)
app//groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1207)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1007)
app//groovy.lang.Closure.call(Closure.java:433)
app//groovy.lang.Closure.call(Closure.java:412)
app//groovy.lang.Closure.run(Closure.java:505)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Actor Thread 5,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)
java.base@15.0.2/java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:920)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1056)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Actor Thread 2,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)
java.base@15.0.2/java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:920)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1056)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Thread-1,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:252)
java.base@15.0.2/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:1661)
java.base@15.0.2/java.util.concurrent.LinkedBlockingDeque.pollFirst(LinkedBlockingDeque.java:515)
java.base@15.0.2/java.util.concurrent.LinkedBlockingDeque.poll(LinkedBlockingDeque.java:677)
app//nextflow.util.SimpleAgent.run(SimpleAgent.groovy:89)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
java.base@15.0.2/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.base@15.0.2/java.lang.reflect.Method.invoke(Method.java:564)
app//org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343)
app//groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:328)
app//groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1333)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
app//groovy.lang.MetaClassImpl.invokeMethodClosure(MetaClassImpl.java:1017)
app//groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1207)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1007)
app//groovy.lang.Closure.call(Closure.java:433)
app//groovy.lang.Closure.call(Closure.java:412)
app//groovy.lang.Closure.run(Closure.java:505)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[main,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:341)
java.base@15.0.2/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:505)
java.base@15.0.2/java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3137)
java.base@15.0.2/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1614)
app//nextflow.util.Barrier$_awaitCompletion_closure3.doCall(Barrier.groovy:92)
app//nextflow.util.Barrier$_awaitCompletion_closure3.call(Barrier.groovy)
app//nextflow.extension.Bolts.withLock(Bolts.groovy:337)
app//nextflow.extension.Bolts.withLock(Bolts.groovy)
app//nextflow.util.Barrier.awaitCompletion(Barrier.groovy:89)
app//nextflow.Session.await(Session.groovy:679)
app//nextflow.script.ScriptRunner.await(ScriptRunner.groovy:256)
app//nextflow.script.ScriptRunner.execute(ScriptRunner.groovy:144)
app//nextflow.cli.CmdRun.run(CmdRun.groovy:376)
app//nextflow.cli.Launcher.run(Launcher.groovy:503)
app//nextflow.cli.Launcher.main(Launcher.groovy:658)
Thread[Notification Thread,9,system]
Thread[Reference Handler,10,system]
java.base@15.0.2/java.lang.ref.Reference.waitForReferencePendingList(Native Method)
java.base@15.0.2/java.lang.ref.Reference.processPendingReferences(Reference.java:241)
java.base@15.0.2/java.lang.ref.Reference$ReferenceHandler.run(Reference.java:213)
Thread[Actor Thread 10,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)
java.base@15.0.2/java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:920)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1056)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Actor Thread 8,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)
java.base@15.0.2/java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:920)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1056)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Actor Thread 1,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)
java.base@15.0.2/java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:920)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1056)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Actor Thread 6,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)
java.base@15.0.2/java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:920)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1056)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[SIGINT handler,9,system]
java.base@15.0.2/java.lang.Thread.dumpThreads(Native Method)
java.base@15.0.2/java.lang.Thread.getAllStackTraces(Thread.java:1649)
app//nextflow.util.SysHelper.dumpThreads(SysHelper.groovy:188)
app//nextflow.Session.abort(Session.groovy:800)
app//nextflow.Session$_registerSignalHandlers_closure17.doCall(Session.groovy:489)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
java.base@15.0.2/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.base@15.0.2/java.lang.reflect.Method.invoke(Method.java:564)
app//org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343)
app//groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:328)
app//org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:279)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1007)
app//groovy.lang.Closure.call(Closure.java:433)
app//org.codehaus.groovy.runtime.ConvertedClosure.invokeCustom(ConvertedClosure.java:52)
app//org.codehaus.groovy.runtime.ConversionHandler.invoke(ConversionHandler.java:113)
com.sun.proxy.$Proxy26.handle(Unknown Source)
jdk.unsupported@15.0.2/sun.misc.Signal$InternalMiscHandler.handle(Signal.java:198)
java.base@15.0.2/jdk.internal.misc.Signal$1.run(Signal.java:220)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Actor Thread 9,5,main]
java.base@15.0.2/java.lang.ClassLoader.defineClass1(Native Method)
java.base@15.0.2/java.lang.ClassLoader.defineClass(ClassLoader.java:1016)
java.base@15.0.2/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:151)
java.base@15.0.2/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:825)
java.base@15.0.2/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:723)
java.base@15.0.2/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:646)
java.base@15.0.2/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:604)
java.base@15.0.2/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:168)
java.base@15.0.2/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
app//com.esotericsoftware.kryo.Kryo.<init>(Kryo.java:188)
app//com.esotericsoftware.kryo.Kryo.<init>(Kryo.java:132)
java.base@15.0.2/java.lang.invoke.DirectMethodHandle$Holder.newInvokeSpecial(DirectMethodHandle$Holder)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c2b440.invoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c2ac40.guardWithCatch(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfbc40.reinvoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfc040.guard(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfbc40.reinvoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c2dc40.invoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c0a440.invokeExact_MT(LambdaForm$MH)
app//org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache(IndyInterface.java:321)
java.base@15.0.2/java.lang.invoke.LambdaForm$DMH/0x0000000800bdd440.invokeStatic(LambdaForm$DMH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfa440.invoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.Invokers$Holder.linkToCallSite(Invokers$Holder)
app//nextflow.util.KryoHelper.newInstance(SerializationHelper.groovy:87)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
java.base@15.0.2/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.base@15.0.2/java.lang.reflect.Method.invoke(Method.java:564)
app//org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343)
app//groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:328)
app//groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1586)
app//org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:611)
app//org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:182)
app//nextflow.util.KryoHelper$1.methodMissing(SerializationHelper.groovy)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
java.base@15.0.2/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.base@15.0.2/java.lang.reflect.Method.invoke(Method.java:564)
app//org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343)
app//groovy.lang.MetaClassImpl.invokeMissingMethod(MetaClassImpl.java:924)
app//groovy.lang.MetaClassImpl.invokePropertyOrMissing(MetaClassImpl.java:1413)
app//groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1335)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1007)
java.base@15.0.2/java.lang.invoke.LambdaForm$DMH/0x0000000800bff440.invokeInterface(LambdaForm$DMH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c9f840.invoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800cac040.invoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c2ac40.guardWithCatch(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfbc40.reinvoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfc040.guard(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfbc40.reinvoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfc040.guard(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfbc40.reinvoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c2dc40.invoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c0a440.invokeExact_MT(LambdaForm$MH)
app//org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache(IndyInterface.java:321)
java.base@15.0.2/java.lang.invoke.LambdaForm$DMH/0x0000000800bdd440.invokeStatic(LambdaForm$DMH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfa440.invoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.Invokers$Holder.linkToCallSite(Invokers$Holder)
app//nextflow.util.KryoHelper$1.initialValue(SerializationHelper.groovy:60)
app//nextflow.util.KryoHelper$1.initialValue(SerializationHelper.groovy)
java.base@15.0.2/java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:195)
java.base@15.0.2/java.lang.ThreadLocal.get(ThreadLocal.java:172)
java.base@15.0.2/java.lang.invoke.DirectMethodHandle$Holder.invokeVirtual(DirectMethodHandle$Holder)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c2ac40.guardWithCatch(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfbc40.reinvoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfc040.guard(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfbc40.reinvoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfc040.guard(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfbc40.reinvoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c2dc40.invoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c0a440.invokeExact_MT(LambdaForm$MH)
app//org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache(IndyInterface.java:321)
java.base@15.0.2/java.lang.invoke.LambdaForm$DMH/0x0000000800bdd440.invokeStatic(LambdaForm$DMH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfa440.invoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.Invokers$Holder.linkToCallSite(Invokers$Holder)
app//nextflow.util.KryoHelper.kryo(SerializationHelper.groovy:79)
java.base@15.0.2/java.lang.invoke.LambdaForm$DMH/0x0000000800b8fc40.invokeStatic(LambdaForm$DMH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c2b440.invoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c2ac40.guardWithCatch(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfbc40.reinvoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfc040.guard(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfbc40.reinvoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c2dc40.invoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c0a440.invokeExact_MT(LambdaForm$MH)
app//org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache(IndyInterface.java:321)
java.base@15.0.2/java.lang.invoke.LambdaForm$DMH/0x0000000800bdd440.invokeStatic(LambdaForm$DMH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfa440.invoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.Invokers$Holder.linkToCallSite(Invokers$Holder)
app//nextflow.util.KryoHelper.serialize(SerializationHelper.groovy:166)
app//nextflow.trace.TraceRecord.serialize(TraceRecord.groovy:573)
app//nextflow.cache.CacheDB.writeTaskEntry0(CacheDB.groovy:147)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
java.base@15.0.2/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.base@15.0.2/java.lang.reflect.Method.invoke(Method.java:564)
app//org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343)
app//groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:328)
app//groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1333)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1007)
app//org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:645)
app//org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:628)
app//org.codehaus.groovy.runtime.InvokerHelper.invokeMethodSafe(InvokerHelper.java:82)
app//nextflow.cache.CacheDB$_putTaskAsync_closure1.doCall(CacheDB.groovy:157)
app//nextflow.cache.CacheDB$_putTaskAsync_closure1.call(CacheDB.groovy)
app//groovyx.gpars.agent.AgentBase.onMessage(AgentBase.java:102)
app//groovyx.gpars.agent.Agent.handleMessage(Agent.java:84)
app//groovyx.gpars.agent.AgentCore$1.handleMessage(AgentCore.java:48)
app//groovyx.gpars.util.AsyncMessagingCore.run(AsyncMessagingCore.java:132)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[AnsiLogObserver,5,main]
java.base@15.0.2/java.util.regex.Pattern$BmpCharProperty.match(Pattern.java:4020)
java.base@15.0.2/java.util.regex.Pattern$GroupHead.match(Pattern.java:4855)
java.base@15.0.2/java.util.regex.Pattern$Branch.match(Pattern.java:4798)
java.base@15.0.2/java.util.regex.Pattern$Branch.match(Pattern.java:4798)
java.base@15.0.2/java.util.regex.Pattern$Branch.match(Pattern.java:4798)
java.base@15.0.2/java.util.regex.Pattern$BranchConn.match(Pattern.java:4763)
java.base@15.0.2/java.util.regex.Pattern$GroupTail.match(Pattern.java:4886)
java.base@15.0.2/java.util.regex.Pattern$BmpCharPropertyGreedy.match(Pattern.java:4394)
java.base@15.0.2/java.util.regex.Pattern$GroupHead.match(Pattern.java:4855)
java.base@15.0.2/java.util.regex.Pattern$Branch.match(Pattern.java:4800)
java.base@15.0.2/java.util.regex.Pattern$Branch.match(Pattern.java:4798)
java.base@15.0.2/java.util.regex.Pattern$BmpCharProperty.match(Pattern.java:4020)
java.base@15.0.2/java.util.regex.Pattern$Start.match(Pattern.java:3673)
java.base@15.0.2/java.util.regex.Matcher.search(Matcher.java:1729)
java.base@15.0.2/java.util.regex.Matcher.find(Matcher.java:773)
java.base@15.0.2/java.util.Formatter.parse(Formatter.java:2702)
java.base@15.0.2/java.util.Formatter.format(Formatter.java:2655)
java.base@15.0.2/java.util.Formatter.format(Formatter.java:2609)
java.base@15.0.2/java.lang.String.format(String.java:3292)
app//jline.internal.TerminalLineSettings.stty(TerminalLineSettings.java:168)
app//jline.internal.TerminalLineSettings.get(TerminalLineSettings.java:72)
app//jline.internal.TerminalLineSettings.getProperty(TerminalLineSettings.java:92)
app//jline.UnixTerminal.getWidth(UnixTerminal.java:77)
app//nextflow.trace.AnsiLogObserver.renderProcesses(AnsiLogObserver.groovy:257)
app//nextflow.trace.AnsiLogObserver.renderProgress(AnsiLogObserver.groovy:312)
app//nextflow.trace.AnsiLogObserver.render0(AnsiLogObserver.groovy:183)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
java.base@15.0.2/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.base@15.0.2/java.lang.reflect.Method.invoke(Method.java:564)
app//org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343)
app//groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:328)
app//groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1333)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
app//groovy.lang.MetaClassImpl.invokeMethodClosure(MetaClassImpl.java:1017)
app//groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1207)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1007)
app//groovy.lang.Closure.call(Closure.java:433)
app//groovy.lang.Closure.call(Closure.java:412)
app//groovy.lang.Closure.run(Closure.java:505)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[TaskFinalizer-1,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:341)
java.base@15.0.2/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:505)
java.base@15.0.2/java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3137)
java.base@15.0.2/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1614)
java.base@15.0.2/java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:435)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1056)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Actor Thread 4,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)
java.base@15.0.2/java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:920)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1056)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Task monitor,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:252)
java.base@15.0.2/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1746)
app//nextflow.processor.TaskPollingMonitor$_await_closure5.doCall(TaskPollingMonitor.groovy:529)
app//nextflow.processor.TaskPollingMonitor$_await_closure5.call(TaskPollingMonitor.groovy)
app//nextflow.extension.Bolts.withLock(Bolts.groovy:337)
app//nextflow.extension.Bolts.withLock(Bolts.groovy)
app//nextflow.processor.TaskPollingMonitor.await(TaskPollingMonitor.groovy:528)
app//nextflow.processor.TaskPollingMonitor.pollLoop(TaskPollingMonitor.groovy:453)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
java.base@15.0.2/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.base@15.0.2/java.lang.reflect.Method.invoke(Method.java:564)
app//org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343)
app//groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:328)
app//groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1333)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1007)
app//org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:645)
app//org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:628)
app//org.codehaus.groovy.runtime.InvokerHelper.invokeMethodSafe(InvokerHelper.java:82)
app//nextflow.processor.TaskPollingMonitor$_start_closure2.doCall(TaskPollingMonitor.groovy:318)
app//nextflow.processor.TaskPollingMonitor$_start_closure2.call(TaskPollingMonitor.groovy)
app//groovy.lang.Closure.run(Closure.java:505)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Actor Thread 11,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)
java.base@15.0.2/java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:920)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1056)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Actor Thread 7,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)
java.base@15.0.2/java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:920)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1056)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Signal Dispatcher,9,system]
Thread[Actor Thread 3,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)
java.base@15.0.2/java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:920)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1056)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Common-Cleaner,8,InnocuousThreadGroup]
java.base@15.0.2/java.lang.Object.wait(Native Method)
java.base@15.0.2/java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:155)
java.base@15.0.2/jdk.internal.ref.CleanerImpl.run(CleanerImpl.java:148)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
java.base@15.0.2/jdk.internal.misc.InnocuousThread.run(InnocuousThread.java:134)
Thread[Finalizer,8,system]
java.base@15.0.2/java.lang.Object.wait(Native Method)
java.base@15.0.2/java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:155)
java.base@15.0.2/java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:176)
java.base@15.0.2/java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:170)
Mar-23 11:44:32.701 [main] DEBUG nextflow.Session - Session await > all barriers passed
Mar-23 11:44:32.701 [Task monitor] DEBUG n.processor.TaskPollingMonitor - <<< barrier arrives (monitor: local) - terminating tasks monitor poll loop
Mar-23 11:44:32.736 [main] DEBUG n.trace.WorkflowStatsObserver - Workflow completed > WorkflowStats[succeededCount=0; failedCount=1; ignoredCount=0; cachedCount=0; pendingCount=0; submittedCount=0; runningCount=0; retriesCount=0; abortedCount=0; succeedDuration=0ms; failedDuration=1s; cachedDuration=0ms;loadCpus=0; loadMemory=0; peakRunning=1; peakCpus=1; peakMemory=0; ]
Mar-23 11:44:32.741 [main] DEBUG nextflow.trace.TraceFileObserver - Workflow completed -- saving trace file
Mar-23 11:44:33.181 [main] DEBUG nextflow.cache.CacheDB - Closing CacheDB done
Mar-23 11:44:33.291 [main] DEBUG nextflow.script.ScriptRunner - > Execution complete -- Goodbye

516
.nextflow.log.2 Normal file
View File

@@ -0,0 +1,516 @@
Mar-23 11:39:29.066 [main] DEBUG nextflow.cli.Launcher - $> nextflow run main.nf --disease_name 'Multiple Sclerosis' --population 10
Mar-23 11:39:29.325 [main] DEBUG nextflow.cli.CmdRun - N E X T F L O W ~ version 24.10.5
Mar-23 11:39:29.404 [main] DEBUG nextflow.plugin.PluginsFacade - Setting up plugin manager > mode=prod; embedded=false; plugins-dir=/Users/richman/.nextflow/plugins; core-plugins: nf-amazon@2.9.2,nf-azure@1.10.2,nf-cloudcache@0.4.2,nf-codecommit@0.2.2,nf-console@1.1.4,nf-google@1.15.4,nf-tower@1.9.3,nf-wave@1.7.4
Mar-23 11:39:29.449 [main] INFO o.pf4j.DefaultPluginStatusProvider - Enabled plugins: []
Mar-23 11:39:29.451 [main] INFO o.pf4j.DefaultPluginStatusProvider - Disabled plugins: []
Mar-23 11:39:29.462 [main] INFO org.pf4j.DefaultPluginManager - PF4J version 3.12.0 in 'deployment' mode
Mar-23 11:39:29.488 [main] INFO org.pf4j.AbstractPluginManager - No plugins
Mar-23 11:39:29.572 [main] DEBUG nextflow.config.ConfigBuilder - Found config local: /Users/richman/workspace/synthea-alldiseases/nextflow.config
Mar-23 11:39:29.583 [main] DEBUG nextflow.config.ConfigBuilder - Parsing config file: /Users/richman/workspace/synthea-alldiseases/nextflow.config
Mar-23 11:39:29.682 [main] DEBUG n.secret.LocalSecretsProvider - Secrets store: /Users/richman/.nextflow/secrets/store.json
Mar-23 11:39:29.689 [main] DEBUG nextflow.secret.SecretsLoader - Discovered secrets providers: [nextflow.secret.LocalSecretsProvider@19542407] - activable => nextflow.secret.LocalSecretsProvider@19542407
Mar-23 11:39:29.780 [main] DEBUG nextflow.config.ConfigBuilder - Applying config profile: `standard`
Mar-23 11:39:31.723 [main] DEBUG nextflow.cli.CmdRun - Applied DSL=2 from script declaration
Mar-23 11:39:31.763 [main] DEBUG nextflow.cli.CmdRun - Launching `main.nf` [astonishing_wozniak] DSL2 - revision: ab2562e4a1
Mar-23 11:39:31.770 [main] DEBUG nextflow.plugin.PluginsFacade - Plugins default=[]
Mar-23 11:39:31.770 [main] DEBUG nextflow.plugin.PluginsFacade - Plugins resolved requirement=[]
Mar-23 11:39:31.897 [main] DEBUG nextflow.Session - Session UUID: cfdf2b28-2b73-4c6f-ac03-fc646888e313
Mar-23 11:39:31.898 [main] DEBUG nextflow.Session - Run name: astonishing_wozniak
Mar-23 11:39:31.899 [main] DEBUG nextflow.Session - Executor pool size: 10
Mar-23 11:39:31.917 [main] DEBUG nextflow.file.FilePorter - File porter settings maxRetries=3; maxTransfers=50; pollTimeout=null
Mar-23 11:39:31.928 [main] DEBUG nextflow.util.ThreadPoolBuilder - Creating thread pool 'FileTransfer' minSize=10; maxSize=30; workQueue=LinkedBlockingQueue[-1]; allowCoreThreadTimeout=false
Mar-23 11:39:31.993 [main] DEBUG nextflow.cli.CmdRun -
Version: 24.10.5 build 5935
Created: 04-03-2025 17:55 UTC (09:55 PDT)
System: Mac OS X 10.16
Runtime: Groovy 4.0.23 on OpenJDK 64-Bit Server VM 15.0.2+7-27
Encoding: UTF-8 (UTF-8)
Process: 72268@MacBookPro.localdomain [192.168.1.157]
CPUs: 10 - Mem: 32 GB (16.7 MB) - Swap: 6 GB (1.6 GB)
Mar-23 11:39:32.031 [main] DEBUG nextflow.Session - Work-dir: /Users/richman/workspace/synthea-alldiseases/work [Mac OS X]
Mar-23 11:39:32.032 [main] DEBUG nextflow.Session - Script base path does not exist or is not a directory: /Users/richman/workspace/synthea-alldiseases/bin
Mar-23 11:39:32.054 [main] DEBUG nextflow.executor.ExecutorFactory - Extension executors providers=[]
Mar-23 11:39:32.072 [main] DEBUG nextflow.Session - Observer factory: DefaultObserverFactory
Mar-23 11:39:32.148 [main] DEBUG nextflow.cache.CacheFactory - Using Nextflow cache factory: nextflow.cache.DefaultCacheFactory
Mar-23 11:39:32.180 [main] DEBUG nextflow.util.CustomThreadPool - Creating default thread pool > poolSize: 11; maxThreads: 1000
Mar-23 11:39:32.248 [main] DEBUG nextflow.Session - Session start
Mar-23 11:39:32.255 [main] DEBUG nextflow.trace.TraceFileObserver - Workflow started -- trace file: /Users/richman/workspace/synthea-alldiseases/trace.txt
Mar-23 11:39:33.528 [main] DEBUG nextflow.script.ScriptRunner - > Launching execution
Mar-23 11:39:33.813 [main] DEBUG nextflow.executor.ExecutorFactory - << taskConfig executor: local
Mar-23 11:39:33.814 [main] DEBUG nextflow.executor.ExecutorFactory - >> processorType: 'local'
Mar-23 11:39:33.827 [main] DEBUG nextflow.executor.Executor - [warm up] executor > local
Mar-23 11:39:33.835 [main] DEBUG n.processor.LocalPollingMonitor - Creating local task monitor for executor 'local' > cpus=10; memory=32 GB; capacity=10; pollInterval=100ms; dumpInterval=5m
Mar-23 11:39:33.843 [main] DEBUG n.processor.TaskPollingMonitor - >>> barrier register (monitor: local)
Mar-23 11:39:33.995 [main] DEBUG nextflow.executor.ExecutorFactory - << taskConfig executor: local
Mar-23 11:39:33.996 [main] DEBUG nextflow.executor.ExecutorFactory - >> processorType: 'local'
Mar-23 11:39:34.025 [main] DEBUG nextflow.Session - Workflow process names [dsl2]: checkAndGetModule, generatePatients
Mar-23 11:39:34.027 [main] DEBUG nextflow.Session - Igniting dataflow network (2)
Mar-23 11:39:34.028 [main] DEBUG nextflow.processor.TaskProcessor - Starting process > checkAndGetModule
Mar-23 11:39:34.028 [main] DEBUG nextflow.processor.TaskProcessor - Starting process > generatePatients
Mar-23 11:39:34.029 [main] DEBUG nextflow.script.ScriptRunner - Parsed script files:
Script_b4244dfae6385692: /Users/richman/workspace/synthea-alldiseases/main.nf
Mar-23 11:39:34.030 [main] DEBUG nextflow.script.ScriptRunner - > Awaiting termination
Mar-23 11:39:34.030 [main] DEBUG nextflow.Session - Session await
Mar-23 11:39:34.443 [Task submitter] DEBUG n.executor.local.LocalTaskHandler - Launch cmd line: /bin/bash -ue .command.run
Mar-23 11:39:34.448 [Task submitter] INFO nextflow.Session - [2c/9d944d] Submitted process > checkAndGetModule
Mar-23 11:39:35.759 [Task monitor] DEBUG n.processor.TaskPollingMonitor - Task completed > TaskHandler[id: 1; name: checkAndGetModule; status: COMPLETED; exit: 1; error: -; workDir: /Users/richman/workspace/synthea-alldiseases/work/2c/9d944dfd494af06885892ba6e4f300]
Mar-23 11:39:35.765 [Task monitor] DEBUG nextflow.util.ThreadPoolBuilder - Creating thread pool 'TaskFinalizer' minSize=10; maxSize=30; workQueue=LinkedBlockingQueue[-1]; allowCoreThreadTimeout=false
Mar-23 11:39:35.795 [TaskFinalizer-1] DEBUG nextflow.processor.TaskProcessor - Handling unexpected condition for
task: name=checkAndGetModule; work-dir=/Users/richman/workspace/synthea-alldiseases/work/2c/9d944dfd494af06885892ba6e4f300
error [nextflow.exception.ProcessFailedException]: Process `checkAndGetModule` terminated with an error exit status (1)
Mar-23 11:39:35.835 [TaskFinalizer-1] ERROR nextflow.processor.TaskProcessor - Error executing process > 'checkAndGetModule'
Caused by:
Process `checkAndGetModule` terminated with an error exit status (1)
Command executed:
echo "Looking for module at /app/modules/multiple_sclerosis.json"
if [ -f "/app/modules/multiple_sclerosis.json" ]; then
echo "Module exists, copying..."
cp "/app/modules/multiple_sclerosis.json" .
else
echo "Module not found, generating..."
python3 /app/module_generator/module_generator.py --disease "Multiple Sclerosis" --output "multiple_sclerosis.json"
if [ -f "multiple_sclerosis.json" ]; then
echo "Successfully generated module"
else
echo "Error: Failed to generate module"
exit 1
fi
fi
Command exit status:
1
Command output:
Looking for module at /app/modules/multiple_sclerosis.json
Module not found, generating...
Command error:
Looking for module at /app/modules/multiple_sclerosis.json
Module not found, generating...
Traceback (most recent call last):
File "/app/module_generator/module_generator.py", line 90, in <module>
client = anthropic.Client(api_key=api_key)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/venv/lib/python3.12/site-packages/anthropic/_client.py", line 113, in __init__
super().__init__(
File "/opt/venv/lib/python3.12/site-packages/anthropic/_base_client.py", line 758, in __init__
self._client = http_client or SyncHttpxClientWrapper(
^^^^^^^^^^^^^^^^^^^^^^^
TypeError: Client.__init__() got an unexpected keyword argument 'proxies'
Work dir:
/Users/richman/workspace/synthea-alldiseases/work/2c/9d944dfd494af06885892ba6e4f300
Container:
synthea-module-generator
Tip: you can try to figure out what's wrong by changing to the process work dir and showing the script file named `.command.sh`
Mar-23 11:39:35.906 [main] DEBUG nextflow.Session - Session await > all processes finished
Mar-23 11:39:35.908 [TaskFinalizer-1] DEBUG nextflow.Session - Session aborted -- Cause: Process `checkAndGetModule` terminated with an error exit status (1)
Mar-23 11:39:36.005 [Task monitor] DEBUG n.processor.TaskPollingMonitor - <<< barrier arrives (monitor: local) - terminating tasks monitor poll loop
Mar-23 11:39:36.006 [main] DEBUG nextflow.Session - Session await > all barriers passed
Mar-23 11:39:36.050 [main] DEBUG n.trace.WorkflowStatsObserver - Workflow completed > WorkflowStats[succeededCount=0; failedCount=1; ignoredCount=0; cachedCount=0; pendingCount=0; submittedCount=0; runningCount=0; retriesCount=0; abortedCount=0; succeedDuration=0ms; failedDuration=1.3s; cachedDuration=0ms;loadCpus=0; loadMemory=0; peakRunning=1; peakCpus=1; peakMemory=0; ]
Mar-23 11:39:36.063 [main] DEBUG nextflow.trace.TraceFileObserver - Workflow completed -- saving trace file
Mar-23 11:39:36.063 [TaskFinalizer-1] DEBUG nextflow.Session -
Thread[Actor Thread 4,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)
java.base@15.0.2/java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:920)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1056)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Reference Handler,10,system]
java.base@15.0.2/java.lang.ref.Reference.waitForReferencePendingList(Native Method)
java.base@15.0.2/java.lang.ref.Reference.processPendingReferences(Reference.java:241)
java.base@15.0.2/java.lang.ref.Reference$ReferenceHandler.run(Reference.java:213)
Thread[Task submitter,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:341)
java.base@15.0.2/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:505)
java.base@15.0.2/java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3137)
java.base@15.0.2/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1614)
app//nextflow.processor.TaskPollingMonitor.awaitTasks(TaskPollingMonitor.groovy:388)
app//nextflow.processor.TaskPollingMonitor.submitLoop(TaskPollingMonitor.groovy:412)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
java.base@15.0.2/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.base@15.0.2/java.lang.reflect.Method.invoke(Method.java:564)
app//org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343)
app//groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:328)
app//groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1333)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
app//groovy.lang.MetaClassImpl.invokeMethodClosure(MetaClassImpl.java:1017)
app//groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1207)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1007)
app//groovy.lang.Closure.call(Closure.java:433)
app//groovy.lang.Closure.call(Closure.java:412)
app//groovy.lang.Closure.run(Closure.java:505)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[TaskFinalizer-1,5,main]
java.base@15.0.2/java.lang.Thread.dumpThreads(Native Method)
java.base@15.0.2/java.lang.Thread.getAllStackTraces(Thread.java:1649)
app//nextflow.util.SysHelper.dumpThreads(SysHelper.groovy:188)
app//nextflow.Session.abort(Session.groovy:800)
app//nextflow.Session.fault(Session.groovy:766)
app//nextflow.processor.TaskPollingMonitor.finalizeTask(TaskPollingMonitor.groovy:695)
app//nextflow.processor.TaskPollingMonitor.safeFinalizeTask(TaskPollingMonitor.groovy:678)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
java.base@15.0.2/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.base@15.0.2/java.lang.reflect.Method.invoke(Method.java:564)
app//org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343)
app//groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:328)
app//groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1333)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1007)
app//org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:645)
app//org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:628)
app//org.codehaus.groovy.runtime.InvokerHelper.invokeMethodSafe(InvokerHelper.java:82)
app//nextflow.processor.TaskPollingMonitor$_checkTaskStatus_lambda8.doCall(TaskPollingMonitor.groovy:668)
app//nextflow.processor.TaskPollingMonitor$$Lambda$437/0x0000000800f4c0e8.run(Unknown Source)
java.base@15.0.2/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
java.base@15.0.2/java.util.concurrent.FutureTask.run(FutureTask.java:264)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Actor Thread 1,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)
java.base@15.0.2/java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:920)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1056)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Actor Thread 2,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)
java.base@15.0.2/java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:920)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1056)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Actor Thread 7,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)
java.base@15.0.2/java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:920)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1056)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Actor Thread 9,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)
java.base@15.0.2/java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:920)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1056)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Actor Thread 5,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)
java.base@15.0.2/java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:920)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1056)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[process reaper,10,system]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:252)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:462)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)
java.base@15.0.2/java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:937)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1055)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Common-Cleaner,8,InnocuousThreadGroup]
java.base@15.0.2/java.lang.Object.wait(Native Method)
java.base@15.0.2/java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:155)
java.base@15.0.2/jdk.internal.ref.CleanerImpl.run(CleanerImpl.java:148)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
java.base@15.0.2/jdk.internal.misc.InnocuousThread.run(InnocuousThread.java:134)
Thread[Notification Thread,9,system]
Thread[Actor Thread 11,5,main]
java.base@15.0.2/java.util.jar.Attributes.get(Attributes.java:104)
java.base@15.0.2/java.util.jar.Attributes.getValue(Attributes.java:140)
java.base@15.0.2/jdk.internal.loader.BuiltinClassLoader.definePackage(BuiltinClassLoader.java:928)
java.base@15.0.2/jdk.internal.loader.BuiltinClassLoader.defineOrCheckPackage(BuiltinClassLoader.java:844)
java.base@15.0.2/jdk.internal.loader.ClassLoaders$AppClassLoader.defineOrCheckPackage(ClassLoaders.java:191)
java.base@15.0.2/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:812)
java.base@15.0.2/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:723)
java.base@15.0.2/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:646)
java.base@15.0.2/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:604)
java.base@15.0.2/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:168)
java.base@15.0.2/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
app//nextflow.util.KryoHelper.newInstance(SerializationHelper.groovy:91)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
java.base@15.0.2/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.base@15.0.2/java.lang.reflect.Method.invoke(Method.java:564)
app//org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343)
app//groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:328)
app//groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1586)
app//org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:611)
app//org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:182)
app//nextflow.util.KryoHelper$1.methodMissing(SerializationHelper.groovy)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
java.base@15.0.2/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.base@15.0.2/java.lang.reflect.Method.invoke(Method.java:564)
app//org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343)
app//groovy.lang.MetaClassImpl.invokeMissingMethod(MetaClassImpl.java:924)
app//groovy.lang.MetaClassImpl.invokePropertyOrMissing(MetaClassImpl.java:1413)
app//groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1335)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1007)
java.base@15.0.2/java.lang.invoke.LambdaForm$DMH/0x0000000800bff440.invokeInterface(LambdaForm$DMH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c9f840.invoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800cae440.invoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c2ac40.guardWithCatch(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfbc40.reinvoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfc040.guard(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfbc40.reinvoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfc040.guard(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfbc40.reinvoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c2dc40.invoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c0a440.invokeExact_MT(LambdaForm$MH)
app//org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache(IndyInterface.java:321)
java.base@15.0.2/java.lang.invoke.LambdaForm$DMH/0x0000000800bdd440.invokeStatic(LambdaForm$DMH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfa440.invoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.Invokers$Holder.linkToCallSite(Invokers$Holder)
app//nextflow.util.KryoHelper$1.initialValue(SerializationHelper.groovy:60)
app//nextflow.util.KryoHelper$1.initialValue(SerializationHelper.groovy)
java.base@15.0.2/java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:195)
java.base@15.0.2/java.lang.ThreadLocal.get(ThreadLocal.java:172)
java.base@15.0.2/java.lang.invoke.DirectMethodHandle$Holder.invokeVirtual(DirectMethodHandle$Holder)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c2ac40.guardWithCatch(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfbc40.reinvoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfc040.guard(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfbc40.reinvoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfc040.guard(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfbc40.reinvoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c2dc40.invoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c0a440.invokeExact_MT(LambdaForm$MH)
app//org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache(IndyInterface.java:321)
java.base@15.0.2/java.lang.invoke.LambdaForm$DMH/0x0000000800bdd440.invokeStatic(LambdaForm$DMH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfa440.invoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.Invokers$Holder.linkToCallSite(Invokers$Holder)
app//nextflow.util.KryoHelper.kryo(SerializationHelper.groovy:79)
java.base@15.0.2/java.lang.invoke.LambdaForm$DMH/0x0000000800b8fc40.invokeStatic(LambdaForm$DMH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c2b440.invoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c2ac40.guardWithCatch(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfbc40.reinvoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfc040.guard(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfbc40.reinvoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c2dc40.invoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c0a440.invokeExact_MT(LambdaForm$MH)
app//org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache(IndyInterface.java:321)
java.base@15.0.2/java.lang.invoke.LambdaForm$DMH/0x0000000800bdd440.invokeStatic(LambdaForm$DMH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfa440.invoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.Invokers$Holder.linkToCallSite(Invokers$Holder)
app//nextflow.util.KryoHelper.serialize(SerializationHelper.groovy:166)
app//nextflow.trace.TraceRecord.serialize(TraceRecord.groovy:573)
app//nextflow.cache.CacheDB.writeTaskEntry0(CacheDB.groovy:147)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
java.base@15.0.2/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.base@15.0.2/java.lang.reflect.Method.invoke(Method.java:564)
app//org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343)
app//groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:328)
app//groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1333)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1007)
app//org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:645)
app//org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:628)
app//org.codehaus.groovy.runtime.InvokerHelper.invokeMethodSafe(InvokerHelper.java:82)
app//nextflow.cache.CacheDB$_putTaskAsync_closure1.doCall(CacheDB.groovy:157)
app//nextflow.cache.CacheDB$_putTaskAsync_closure1.call(CacheDB.groovy)
app//groovyx.gpars.agent.AgentBase.onMessage(AgentBase.java:102)
app//groovyx.gpars.agent.Agent.handleMessage(Agent.java:84)
app//groovyx.gpars.agent.AgentCore$1.handleMessage(AgentCore.java:48)
app//groovyx.gpars.util.AsyncMessagingCore.run(AsyncMessagingCore.java:132)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Finalizer,8,system]
java.base@15.0.2/java.lang.Object.wait(Native Method)
java.base@15.0.2/java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:155)
java.base@15.0.2/java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:176)
java.base@15.0.2/java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:170)
Thread[Thread-1,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:252)
java.base@15.0.2/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:1661)
java.base@15.0.2/java.util.concurrent.LinkedBlockingDeque.pollFirst(LinkedBlockingDeque.java:515)
java.base@15.0.2/java.util.concurrent.LinkedBlockingDeque.poll(LinkedBlockingDeque.java:677)
app//nextflow.util.SimpleAgent.run(SimpleAgent.groovy:89)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
java.base@15.0.2/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.base@15.0.2/java.lang.reflect.Method.invoke(Method.java:564)
app//org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343)
app//groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:328)
app//groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1333)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
app//groovy.lang.MetaClassImpl.invokeMethodClosure(MetaClassImpl.java:1017)
app//groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1207)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1007)
app//groovy.lang.Closure.call(Closure.java:433)
app//groovy.lang.Closure.call(Closure.java:412)
app//groovy.lang.Closure.run(Closure.java:505)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Actor Thread 6,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)
java.base@15.0.2/java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:920)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1056)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Actor Thread 8,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)
java.base@15.0.2/java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:920)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1056)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[pool-2-thread-1,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:341)
java.base@15.0.2/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:505)
java.base@15.0.2/java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3137)
java.base@15.0.2/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1614)
java.base@15.0.2/java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:435)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1056)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[Signal Dispatcher,9,system]
Thread[Actor Thread 10,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)
java.base@15.0.2/java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:920)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1056)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[AnsiLogObserver,5,main]
java.base@15.0.2/java.lang.Object.wait(Native Method)
app//nextflow.trace.AnsiLogObserver.render0(AnsiLogObserver.groovy:185)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
java.base@15.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
java.base@15.0.2/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.base@15.0.2/java.lang.reflect.Method.invoke(Method.java:564)
app//org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343)
app//groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:328)
app//groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1333)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
app//groovy.lang.MetaClassImpl.invokeMethodClosure(MetaClassImpl.java:1017)
app//groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1207)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
app//groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1007)
app//groovy.lang.Closure.call(Closure.java:433)
app//groovy.lang.Closure.call(Closure.java:412)
app//groovy.lang.Closure.run(Closure.java:505)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Thread[main,5,main]
java.base@15.0.2/sun.invoke.util.VerifyType.isNullConversion(VerifyType.java:70)
java.base@15.0.2/java.lang.invoke.InvokerBytecodeGenerator.emitImplicitConversion(InvokerBytecodeGenerator.java:605)
java.base@15.0.2/java.lang.invoke.InvokerBytecodeGenerator.emitPushArgument(InvokerBytecodeGenerator.java:1691)
java.base@15.0.2/java.lang.invoke.InvokerBytecodeGenerator.emitPushArguments(InvokerBytecodeGenerator.java:1676)
java.base@15.0.2/java.lang.invoke.InvokerBytecodeGenerator.emitStaticInvoke(InvokerBytecodeGenerator.java:1102)
java.base@15.0.2/java.lang.invoke.InvokerBytecodeGenerator.addMethod(InvokerBytecodeGenerator.java:916)
java.base@15.0.2/java.lang.invoke.InvokerBytecodeGenerator.generateCustomizedCodeBytes(InvokerBytecodeGenerator.java:806)
java.base@15.0.2/java.lang.invoke.InvokerBytecodeGenerator.generateCustomizedCode(InvokerBytecodeGenerator.java:764)
java.base@15.0.2/java.lang.invoke.LambdaForm.compileToBytecode(LambdaForm.java:872)
java.base@15.0.2/java.lang.invoke.LambdaForm.customize(LambdaForm.java:507)
java.base@15.0.2/java.lang.invoke.MethodHandle.customize(MethodHandle.java:1753)
java.base@15.0.2/java.lang.invoke.Invokers.maybeCustomize(Invokers.java:604)
java.base@15.0.2/java.lang.invoke.Invokers.checkCustomized(Invokers.java:595)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800c0a440.invokeExact_MT(LambdaForm$MH)
app//org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache(IndyInterface.java:321)
java.base@15.0.2/java.lang.invoke.LambdaForm$DMH/0x0000000800bdd440.invokeStatic(LambdaForm$DMH)
java.base@15.0.2/java.lang.invoke.LambdaForm$MH/0x0000000800bfac40.invoke(LambdaForm$MH)
java.base@15.0.2/java.lang.invoke.Invokers$Holder.linkToCallSite(Invokers$Holder)
app//nextflow.util.LoggerHelper$ConsoleLoggerFilter.decide(LoggerHelper.groovy:425)
app//nextflow.util.LoggerHelper$ConsoleLoggerFilter.decide(LoggerHelper.groovy)
app//ch.qos.logback.core.spi.FilterAttachableImpl.getFilterChainDecision(FilterAttachableImpl.java:57)
app//ch.qos.logback.core.AppenderBase.getFilterChainDecision(AppenderBase.java:132)
app//ch.qos.logback.core.AppenderBase.doAppend(AppenderBase.java:78)
app//ch.qos.logback.core.spi.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:51)
app//ch.qos.logback.classic.Logger.appendLoopOnAppenders(Logger.java:272)
app//ch.qos.logback.classic.Logger.callAppenders(Logger.java:259)
app//ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:426)
app//ch.qos.logback.classic.Logger.filterAndLog_0_Or3Plus(Logger.java:386)
app//ch.qos.logback.classic.Logger.debug(Logger.java:487)
app//nextflow.trace.WorkflowStatsObserver.onFlowComplete(WorkflowStatsObserver.groovy:48)
app//nextflow.Session.notifyFlowComplete(Session.groovy:1155)
app//nextflow.Session.shutdown0(Session.groovy:749)
app//nextflow.Session.destroy(Session.groovy:694)
app//nextflow.script.ScriptRunner.shutdown(ScriptRunner.groovy:260)
app//nextflow.script.ScriptRunner.execute(ScriptRunner.groovy:146)
app//nextflow.cli.CmdRun.run(CmdRun.groovy:376)
app//nextflow.cli.Launcher.run(Launcher.groovy:503)
app//nextflow.cli.Launcher.main(Launcher.groovy:658)
Thread[Actor Thread 3,5,main]
java.base@15.0.2/jdk.internal.misc.Unsafe.park(Native Method)
java.base@15.0.2/java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
java.base@15.0.2/java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)
java.base@15.0.2/java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:920)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1056)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1116)
java.base@15.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
java.base@15.0.2/java.lang.Thread.run(Thread.java:832)
Mar-23 11:39:36.068 [TaskFinalizer-1] WARN nextflow.util.SimpleAgent - Got an interrupted exception while taking agent result | java.lang.InterruptedException
Mar-23 11:39:36.216 [main] DEBUG nextflow.cache.CacheDB - Closing CacheDB done
Mar-23 11:39:36.270 [main] DEBUG nextflow.script.ScriptRunner - > Execution complete -- Goodbye

Binary file not shown.

View File

@@ -0,0 +1 @@
MANIFEST-000002

Binary file not shown.

View File

@@ -0,0 +1 @@
MANIFEST-000002

Binary file not shown.

View File

@@ -0,0 +1 @@
MANIFEST-000002

3
.nextflow/history Normal file
View File

@@ -0,0 +1,3 @@
2025-03-23 11:39:32 4.3s astonishing_wozniak ERR ab2562e4a1267523331e2cb54d077f38 cfdf2b28-2b73-4c6f-ac03-fc646888e313 nextflow run main.nf --disease_name 'Multiple Sclerosis' --population 10
2025-03-23 11:44:28 5.3s distracted_curran ERR ab2562e4a1267523331e2cb54d077f38 ae62d0f9-dec1-462d-a18a-b4b9ebf0f702 nextflow run main.nf --disease_name 'Multiple Sclerosis' --population 10
2025-03-23 11:46:20 4.7s astonishing_jennings ERR eefd5403259f10b637287fe5bd92db05 02e2b57f-ce09-4ca9-9884-4a04f4cc41f5 nextflow run main.nf --disease_name 'Multiple Sclerosis' --population 10

26
CLAUDE.md Normal file
View File

@@ -0,0 +1,26 @@
# Synthea Development Guidelines
## Build & Test Commands
- Build: `./gradlew build`
- Run: `./run_synthea` or `./gradlew run -Params="['arg1', 'arg2']"`
- Clean: `./gradlew cleanOutput`
- Full test: `./gradlew test`
- Single test: `./gradlew test --tests "org.mitre.synthea.TestClassName"`
- Test coverage: `./gradlew jacocoTestReport`
- Style check: `./gradlew checkstyleMain`
- Create JAR: `./gradlew shadowJar`
- Generate module visualizations: `./gradlew graphviz`
## Code Style
- Google Java Style (follows checkstyle.xml)
- Indentation: 2 spaces, no tabs
- Line length: max 100 characters
- Package naming: lowercase with dots (e.g., `org.mitre.synthea`)
- Class naming: CamelCase (e.g., `PatientGenerator`)
- Method naming: camelCase (e.g., `generatePatient`)
- Variable naming: camelCase (first char lowercase)
- Avoid star imports
- Braces required for all control structures
- One statement per line
- Empty catch blocks must name exception as "expected"
- Javadoc required for public methods

104
DOCKER_README.md Normal file
View File

@@ -0,0 +1,104 @@
# Synthea Disease Module Generator
This package provides Docker and Nextflow integrations for Synthea to:
1. Generate disease modules using Claude AI
2. Look up existing disease modules by name
3. Run both functions in a containerized environment
## Prerequisites
- Docker
- Nextflow (will be installed automatically if not present)
- Anthropic API key (Claude)
## Setup
1. **Clone the repository and navigate to it**:
```bash
git clone https://github.com/yourusername/synthea-alldiseases.git
cd synthea-alldiseases
```
2. **Set your Anthropic API key**:
Option 1: Environment variable:
```bash
export ANTHROPIC_API_KEY=your_api_key_here
```
Option 2: You'll be prompted to enter it when you run the script if it's not set.
## Usage
### Running the Module Generator
Use the provided script:
```bash
./run_module_generator.sh --disease_name "Disease Name Here"
```
Additional options:
```
--modules_dir Path to modules directory (default: src/main/resources/modules)
--output_dir Output directory for generated modules (default: output)
--help Show help information
```
### Examples
Generate a module for Multiple Sclerosis:
```bash
./run_module_generator.sh --disease_name "Multiple Sclerosis"
```
Generate a module and save it to a custom location:
```bash
./run_module_generator.sh --disease_name "Parkinson's Disease" --output_dir ./custom_modules
```
### Using Docker Compose (Alternative)
You can also run the entire environment using Docker Compose:
```bash
docker-compose up -d
docker-compose exec synthea bash
```
Once inside the container:
```bash
./run_module_generator.sh --disease_name "Disease Name"
```
## How It Works
The pipeline follows these steps:
1. Check if a module already exists for the disease
2. Look up the disease in the disease list for ICD-10 codes and other metadata
3. If the module exists, copy it to the output directory
4. If the module doesn't exist, generate it using Claude AI
5. Save the module to the specified output directory
6. For new modules, also update the modules directory
## Modifying the Docker Configuration
If you need to customize the Docker environment:
1. Edit `Dockerfile` to add dependencies or change the configuration
2. Rebuild the Docker image:
```bash
docker build -t synthea-module-generator .
```
## Troubleshooting
- **API Key Issues**: Ensure your ANTHROPIC_API_KEY is set correctly
- **Docker Permission Issues**: You may need to run Docker commands with sudo
- **Memory Issues**: For large modules, you may need to increase Docker's memory allocation
- **Pipeline Errors**: Check execution_report.html for detailed error information
## License
This project is licensed under the same license as Synthea.

70
Dockerfile Normal file
View File

@@ -0,0 +1,70 @@
FROM eclipse-temurin:17-jdk
WORKDIR /app
# Install Python and dependencies
RUN apt-get update && apt-get install -y \
python3 \
python3-pip \
python3-venv \
git \
&& rm -rf /var/lib/apt/lists/*
# Set up Python virtual environment
RUN python3 -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
# Install Anthropic and tqdm in the virtual environment
RUN pip3 install --no-cache-dir "anthropic>=0.8.1,<0.9.0" tqdm==4.66.2 python-dotenv==1.0.1
# Clone the official Synthea repository directly into /app
RUN git clone https://github.com/synthetichealth/synthea.git /app-temp && \
cp -r /app-temp/* /app/ && \
rm -rf /app-temp
# Create directory structure for our custom modules and python scripts
RUN mkdir -p /app/module_generator \
/app/output \
/app/src/main/resources/modules
# First build the project with the official modules - this will compile the Java code
RUN ./gradlew build -x test
# Make the run_synthea script executable
RUN chmod +x /app/run_synthea
# Copy our Python scripts and module generators
COPY module_generator/*.py /app/module_generator/
COPY src/main/resources/modules/* /app/src/main/resources/modules/
COPY src/main/resources/disease/* /app/src/main/resources/
COPY scripts/* /app/scripts/
# Make scripts executable
RUN chmod +x /app/module_generator/*.py /app/scripts/*
# Verify and fix module JSON structures
RUN python3 /app/scripts/check_condition_structure.py --modules_dir /app/src/main/resources/modules --verbose
# Create a directory for modules that will be mounted from the host
RUN mkdir -p /app/modules
# Test a simple module generation to ensure Synthea works
RUN ./run_synthea -p 1 -m hypertension
# Set up a symlink from mounted modules to Synthea modules directory
RUN echo '#!/bin/sh\n\
# Update modules symlinks\n\
# Load environment variables\n\
if [ -f /app/.env ]; then\n\
export $(grep -v "^#" /app/.env | xargs)\n\
fi\n\
\n\
exec "$@"' > /app/entrypoint.sh && chmod +x /app/entrypoint.sh
# Set PYTHONPATH to ensure modules can be found
ENV PYTHONPATH="/app"
# Set entrypoint to use our script
ENTRYPOINT ["/app/entrypoint.sh"]
# Default command when container runs
CMD ["tail", "-f", "/dev/null"]

201
LICENSE Normal file
View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

189
README.md
View File

@@ -1,93 +1,144 @@
# synthea-alldiseases
# Synthea All Diseases
A comprehensive pipeline for generating Synthea modules and synthetic patient data for any disease.
## Overview
## Getting started
This pipeline leverages Nextflow to orchestrate the generation of disease modules and synthetic patient data using Synthea. It supports:
To make it easy for you to get started with GitLab, here's a list of recommended next steps.
1. Automatic generation of disease modules using Claude AI
2. Synthetic patient generation with configurable parameters using the actual Synthea engine
3. Analysis of generated patient data
Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)!
## Requirements
## Add your files
- Docker
- Docker Compose
- Nextflow (version 20.10.0 or higher)
- Java (required by Nextflow)
- Python 3.6+ (if running scripts directly)
- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files
- [ ] [Add files using the command line](https://docs.gitlab.com/topics/git/add_files/#add-files-to-a-git-repository) or push an existing Git repository with the following command:
## Quick Start
```
cd existing_repo
git remote add origin https://gitlab.com/omic/next/registry/tools/synthea-alldiseases.git
git branch -M master
git push -uf origin master
The easiest way to get started is to use our convenience scripts:
```bash
# Set up the environment (builds Docker containers and prepares directories)
./scripts/prepare_environment.sh
# Run the pipeline for a specific disease
./scripts/run_pipeline.sh --disease "Parkinson's Disease" --patients --population 50
```
## Integrate with your tools
## Manual Setup
- [ ] [Set up project integrations](https://gitlab.com/omic/next/registry/tools/synthea-alldiseases/-/settings/integrations)
1. Clone this repository:
```bash
git clone https://github.com/yourusername/synthea-alldiseases.git
cd synthea-alldiseases
```
## Collaborate with your team
2. Create a `.env` file with your API keys (or copy from `.env.example`):
```bash
cp .env.example .env
# Edit .env with your preferred text editor
```
- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/)
- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
- [ ] [Set auto-merge](https://docs.gitlab.com/user/project/merge_requests/auto_merge/)
## Test and Deploy
Use the built-in continuous integration in GitLab.
- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/)
- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/)
- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
***
# Editing this README
When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thanks to [makeareadme.com](https://www.makeareadme.com/) for this template.
## Suggestions for a good README
Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information.
## Name
Choose a self-explaining name for your project.
## Description
Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors.
## Badges
On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge.
## Visuals
Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method.
## Installation
Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection.
3. Build and start the Docker containers:
```bash
docker-compose build
docker-compose up -d synthea
```
## Usage
Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README.
## Support
Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc.
### Basic Command
## Roadmap
If you have ideas for releases in the future, it is a good idea to list them in the README.
```bash
nextflow run main.nf --disease_name "Disease Name" [options]
```
## Contributing
State if you are open to contributions and what your requirements are for accepting them.
### Examples
For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self.
Generate a module for Hypertension and create 100 patients:
```bash
nextflow run main.nf --disease_name "Hypertension" --generate_patients true --population 100 --gender 0.6
```
You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser.
Generate a module for Parkinson's Disease, create 50 patients, and analyze the data:
```bash
nextflow run main.nf --disease_name "Parkinson's Disease" --generate_patients true --population 50 --analyze_patient_data true
```
## Authors and acknowledgment
Show your appreciation to those who have contributed to the project.
### Parameters
| Parameter | Description | Default |
|-----------|-------------|---------|
| `--disease_name` | Name of the disease to model | (required) |
| `--modules_dir` | Directory for modules | `modules` |
| `--output_dir` | Directory for output files | `output` |
| `--generate_patients` | Generate patient data | `false` |
| `--population` | Number of patients to generate | `100` |
| `--gender` | Gender distribution (0-1 for % female) | `0.5` |
| `--min_age` | Minimum patient age | `0` |
| `--max_age` | Maximum patient age | `90` |
| `--seed` | Random seed for reproducibility | (random) |
| `--analyze_patient_data` | Analyze generated data | `false` |
| `--report_format` | Format for analysis report | `html` |
| `--force_generate` | Force regeneration of modules | `false` |
| `--publish_dir` | Directory for published output | `published_output` |
## Understanding the Data Flow
1. **Module Generation**: The pipeline first looks for an existing module for the specified disease. If not found, it generates one using the module_generator.
2. **Patient Generation**: If requested, the pipeline uses the actual Synthea engine to generate synthetic patient data based on the disease module.
3. **Analysis**: If requested, the pipeline analyzes the generated patient data and produces reports.
## Directory Structure
- `modules/`: Contains generated disease modules
- `module_generator/`: Contains the AI-powered module generation scripts
- `scripts/`: Utility scripts for the pipeline
- `output/`: Generated patient data (temporary)
- `published_output/`: Final output data that persists between runs
- `published_output/modules/`: Contains the generated modules
- `published_output/{disease_name}/`: Contains patient data for each disease
## Convenience Scripts
- `scripts/prepare_environment.sh`: Sets up the environment and starts containers
- `scripts/run_pipeline.sh`: Simplified interface for running the pipeline
- `scripts/analyze_patient_data.py`: Analyzes generated patient data
- `scripts/check_condition_structure.py`: Validates module JSON structure
## Troubleshooting
If you encounter issues:
1. Check that Docker containers are running:
```bash
docker ps | grep synthea
```
2. Ensure your modules directory has the required modules:
```bash
ls -la modules/
```
3. Check logs for detailed error messages:
```bash
tail -f .nextflow.log
```
4. Try rebuilding the Docker containers:
```bash
docker-compose down
docker-compose build
docker-compose up -d synthea
```
5. If module generation fails, check that your API keys are correctly set in the .env file
## License
For open source projects, say how it is licensed.
## Project status
If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.
This project uses the same license as Synthea.

280
SYNTHEA_GUIDE.md Normal file
View File

@@ -0,0 +1,280 @@
# Synthea Disease Module Generator Guide
This guide explains how to use our Nextflow pipeline to generate Synthea disease modules and synthetic patient data.
## Overview
Our pipeline provides three main functionalities:
1. **Disease Module Generation**: Creates Synthea disease modules using Claude AI
2. **Synthetic Patient Generation**: Uses the generated modules to create synthetic patient data with configurable demographic characteristics
3. **Patient Data Analysis**: Generates statistics and reports from the synthetic patient data
## Prerequisites
- Nextflow installed
- Synthea installed (with Java 8 or 11 compatibility)
- Anthropic API key (for Claude)
## Basic Usage
### 1. Generating Disease Modules
To generate disease modules for specific diseases:
```bash
# Generate a module for a single disease
nextflow run synthea_module_generator.nf --disease_name "Seasonal Allergies"
# Generate modules for multiple diseases
nextflow run synthea_module_generator.nf --disease_name "Asthma,Diabetes,Hypertension"
```
### 2. Generating Synthetic Patients
To generate synthetic patients with the specified diseases:
```bash
# Generate 100 patients with Asthma (default parameters)
nextflow run synthea_module_generator.nf --disease_name "Asthma" --generate_patients true
# Generate 1000 patients with specific parameters
nextflow run synthea_module_generator.nf \
--disease_name "Diabetes" \
--generate_patients true \
--population 1000 \
--gender 0.6 \
--min_age 40 \
--max_age 80 \
--seed 12345 \
--location "Massachusetts"
```
### 3. Analyzing Patient Data
To generate patients and analyze the resulting data:
```bash
# Generate patients and produce an HTML analysis report
nextflow run synthea_module_generator.nf \
--disease_name "Asthma" \
--generate_patients true \
--population 500 \
--analyze_output true \
--report_format html
```
## Available Parameters
### Module Generation Parameters
- `--disease_name`: Name of the disease(s) to generate (comma-separated for multiple)
- `--modules_dir`: Directory for modules (default: `src/main/resources/modules`)
- `--batch_size`: Number of modules to generate per batch (default: 1)
- `--max_cost`: Maximum cost for API calls (default: 5.0 USD)
- `--timeout`: Maximum time per batch in seconds (default: 300)
### Patient Generation Parameters
#### Basic Patient Parameters
- `--generate_patients`: Set to `true` to generate patients (default: `false`)
- `--population`: Number of patients to generate (default: 100)
- `--gender`: Gender distribution - `M`, `F`, or a decimal for percent female (e.g., 0.7 = 70% female)
- `--min_age`: Minimum patient age (default: 0)
- `--max_age`: Maximum patient age (default: 100)
- `--seed`: Random seed for reproducibility (default: 12345)
- `--location`: Location for patients (default: random)
- `--output_dir`: Output directory for patients (default: `output/synthetic_patients`)
#### Enhanced Demographic Parameters
- `--race_ethnicity`: Comma-separated list of races with percentages (e.g., `white=0.7,hispanic=0.15,black=0.15`)
- `--socioeconomic`: Socioeconomic status distribution (e.g., `high=0.2,middle=0.5,low=0.3`)
- `--zip_codes`: Comma-separated list of ZIP codes to distribute patients (e.g., `02138,02139,02140`)
#### Disease Prevalence Parameters
- `--prevalence`: Percentage of population with the disease, between 0.0 and 1.0 (e.g., `0.05` for 5%)
- `--comorbidities`: Whether to include common comorbidities (set to `true` or `false`, default: `false`)
### Analysis Parameters
- `--analyze_output`: Whether to run analysis on the output (default: `false`)
- `--report_format`: Format for the analysis report (`html`, `csv`, `json`) (default: `html`)
## Detailed Configuration Guide
### Controlling Demographics
You can precisely control the demographic distribution of your patient population:
#### Gender Distribution
```bash
# Generate all male patients
nextflow run synthea_module_generator.nf --disease_name "Prostate Cancer" --generate_patients true --gender M
# Generate all female patients
nextflow run synthea_module_generator.nf --disease_name "Ovarian Cancer" --generate_patients true --gender F
# Generate 60% female, 40% male
nextflow run synthea_module_generator.nf --disease_name "Diabetes" --generate_patients true --gender 0.6
```
#### Age Distribution
```bash
# Generate pediatric patients (0-18 years)
nextflow run synthea_module_generator.nf --disease_name "Asthma" --generate_patients true --min_age 0 --max_age 18
# Generate elderly patients (65+ years)
nextflow run synthea_module_generator.nf --disease_name "Parkinsons" --generate_patients true --min_age 65 --max_age 90
```
#### Race and Ethnicity
```bash
# Generate patients with specific racial distribution
nextflow run synthea_module_generator.nf \
--disease_name "Hypertension" \
--generate_patients true \
--race_ethnicity "white=0.6,black=0.2,hispanic=0.15,asian=0.05"
```
#### Socioeconomic Status
```bash
# Generate patients with specific socioeconomic distribution
nextflow run synthea_module_generator.nf \
--disease_name "Diabetes" \
--generate_patients true \
--socioeconomic "high=0.2,middle=0.5,low=0.3"
```
### Disease Prevalence Simulation
You can control the prevalence of diseases in your synthetic population:
```bash
# Generate 1000 patients with 8% diabetes prevalence (realistic for US population)
nextflow run synthea_module_generator.nf \
--disease_name "Diabetes" \
--generate_patients true \
--population 1000 \
--prevalence 0.08
# Generate patients with comorbidities
nextflow run synthea_module_generator.nf \
--disease_name "Hypertension" \
--generate_patients true \
--prevalence 0.3 \
--comorbidities true
```
### Analysis Reports
You can generate analysis reports in various formats:
```bash
# Generate HTML report (default)
nextflow run synthea_module_generator.nf \
--disease_name "Asthma" \
--generate_patients true \
--analyze_output true
# Generate CSV reports
nextflow run synthea_module_generator.nf \
--disease_name "Diabetes" \
--generate_patients true \
--analyze_output true \
--report_format csv
```
## Example Scenarios
### Realistic Diabetes Population
Generate a realistic U.S. diabetes population with proper demographics:
```bash
nextflow run synthea_module_generator.nf \
--disease_name "Diabetes" \
--generate_patients true \
--population 1000 \
--prevalence 0.08 \
--race_ethnicity "white=0.6,black=0.13,hispanic=0.18,asian=0.06,native=0.03" \
--min_age 18 \
--max_age 90 \
--analyze_output true
```
### Pediatric Asthma Study Cohort
Generate a pediatric asthma cohort for a simulated clinical study:
```bash
nextflow run synthea_module_generator.nf \
--disease_name "Asthma" \
--generate_patients true \
--population 500 \
--min_age 5 \
--max_age 17 \
--gender 0.5 \
--prevalence 0.08 \
--analyze_output true \
--report_format html
```
### Multi-Disease Elderly Population
Generate an elderly population with multiple chronic conditions:
```bash
nextflow run synthea_module_generator.nf \
--disease_name "Hypertension,Arthritis,COPD" \
--generate_patients true \
--population 1000 \
--min_age 65 \
--max_age 90 \
--comorbidities true \
--analyze_output true
```
## Analysis Report Details
The analysis report includes:
1. **Patient Demographics**
- Gender distribution
- Age distribution (by age groups)
- Race/ethnicity distribution
2. **Disease Statistics**
- Top 10 conditions in the patient population
- Top 10 medications prescribed
3. **Summary Statistics**
- Total number of patients
- Age ranges (min, max, average)
## Troubleshooting
### Compatibility Issues
If you encounter Java compatibility issues, ensure you're using Java 8 or 11 which are most compatible with Synthea:
```bash
# Set JAVA_HOME to Java 8 before running
export JAVA_HOME=/path/to/java8
```
### Debugging Module Generation
If module generation fails:
1. Check the `.error` file in the modules directory
2. Verify your API key is set correctly
3. Try generating a simpler disease first
### Patient Generation Issues
If patient generation fails:
1. Check that Synthea is properly installed
2. Verify the modules exist in the modules directory
3. Check that parameter values are within valid ranges

47
docker-compose.yml Normal file
View File

@@ -0,0 +1,47 @@
version: '3.8'
services:
synthea:
build:
context: .
dockerfile: Dockerfile
volumes:
- ./modules:/app/modules:ro # Mount modules directory read-only
- ./output:/app/output # Mount output directory for patient data
- ./.env:/app/.env:ro # Mount environment variables file
environment:
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
working_dir: /app
command: tail -f /dev/null # Keep container running
healthcheck:
test: ["CMD", "/app/healthcheck.sh"]
interval: 30s
timeout: 10s
retries: 3
start_period: 5s
restart: unless-stopped
ports:
- "8080:8080" # Only needed if you want to access the Synthea web interface
module-generator:
build:
context: .
dockerfile: Dockerfile
volumes:
- ./modules:/app/modules # Mount modules directory for writing
- ./module_generator:/app/module_generator
- ./src:/app/src
- ./scripts:/app/scripts
- ./.env:/app/.env:ro # Mount environment variables file
environment:
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
working_dir: /app
command: python3 /app/module_generator/run_module_generator.py --batch-size 5 --max-modules 10 --prioritize
depends_on:
- synthea
profiles:
- generator # This service won't start by default, only when explicitly requested
volumes:
synthea-output:
driver: local

128
main.nf Normal file
View File

@@ -0,0 +1,128 @@
#!/usr/bin/env nextflow
nextflow.enable.dsl=2
/*
* Synthea Disease Module Generator Pipeline
*
* A Nextflow pipeline to generate and manage Synthea disease modules
*/
// Load API key from .env file if it exists
def envFile = file('.env')
if (envFile.exists()) {
envFile.eachLine { line ->
def (key, value) = line.tokenize('=')
if (key && value && key.trim() == 'ANTHROPIC_API_KEY') {
params.anthropic_api_key = value.trim()
}
}
}
// Default parameters
params.disease_name = null // Disease name to generate patients for
params.output_dir = "output" // Output directory
params.modules_dir = "src/main/resources/modules" // Directory for module files
params.population = 100 // Number of patients to generate
params.gender = 0.5 // Decimal representing proportion female (0.0-1.0)
params.min_age = 0 // Minimum age of generated patients
params.max_age = 90 // Maximum age of generated patients
params.seed = null // Random seed for reproducibility
params.help = false // Show help message
// Show help message
if (params.help) {
log.info """
Synthea Patient Generator
========================
Usage: nextflow run main.nf --disease_name "Disease Name"
Required Arguments:
--disease_name Disease name to generate patients for
Optional Arguments:
--modules_dir Module directory (default: modules)
--output_dir Output directory (default: output)
--population Number of patients (default: 100)
--gender Gender ratio - female proportion 0.0-1.0 (default: 0.5)
--min_age Minimum age (default: 0)
--max_age Maximum age (default: 90)
--seed Random seed (default: random)
"""
exit 0
}
// Validate required parameters
if (!params.disease_name && !params.help) {
error "Disease name is required. Please specify with --disease_name"
}
// Process to check if module exists and generate it if needed
process checkAndGetModule {
container 'synthea-module-generator'
publishDir "${params.modules_dir}", mode: 'copy'
input:
val diseaseName
output:
path "*.json", emit: module_file
script:
def moduleFilename = diseaseName.toLowerCase().replaceAll(' ', '_') + '.json'
def fullPath = "/app/src/main/resources/modules/${moduleFilename}"
"""
echo "Looking for module at ${fullPath}"
if [ -f "${fullPath}" ]; then
echo "Module exists, copying..."
cp "${fullPath}" .
else
echo "Module not found, generating..."
python3 /app/module_generator/module_generator.py --disease "${diseaseName}" --output "${moduleFilename}"
if [ -f "${moduleFilename}" ]; then
echo "Successfully generated module"
else
echo "Error: Failed to generate module"
exit 1
fi
fi
"""
}
// Process to generate synthetic patients
process generatePatients {
container 'synthea-module-generator'
publishDir "${params.output_dir}/${diseaseName.toLowerCase().replaceAll(' ', '_')}", mode: 'copy'
input:
val diseaseName
path moduleFile
output:
path "m/*", optional: true
path "f/*", optional: true
script:
def moduleBasename = diseaseName.toLowerCase().replaceAll(' ', '_')
def genderArg = params.gender < 0.5 ? "M" : (params.gender > 0.5 ? "F" : "B")
def seedValue = params.seed ?: new Random().nextInt(1000000)
"""
# Copy module and run Synthea
cp "${moduleFile}" /app/modules/
cd /app && ./run_synthea -p ${params.population} -g ${genderArg} -m ${moduleBasename} -a ${params.min_age}-${params.max_age} -s ${seedValue}
# Organize output by gender
mkdir -p m f
find /app/output/fhir -type f -name "*.json" ! -name "*hospital*" ! -name "*practitioner*" | xargs grep -l '"gender":"male"' | xargs -I{} cp {} m/
find /app/output/fhir -type f -name "*.json" ! -name "*hospital*" ! -name "*practitioner*" | xargs grep -l '"gender":"female"' | xargs -I{} cp {} f/
"""
}
// Define workflow
workflow {
// First check if the module exists
checkAndGetModule(params.disease_name)
// Then generate patients
generatePatients(params.disease_name, checkAndGetModule.out.module_file)
}

View File

@@ -0,0 +1,83 @@
# Synthea Module Generator
This tool automates the creation of disease modules for Synthea based on `disease_list.json`. It uses Claude 3.7 to generate appropriate JSON structures for each disease, leveraging existing modules as templates.
## Prerequisites
1. Python 3.6+
2. Required Python packages:
```
pip install anthropic tqdm
```
3. Anthropic API key:
```
export ANTHROPIC_API_KEY=your_api_key
```
## Usage
```bash
# Generate 10 modules (default limit)
python module_generator.py
# Generate modules only for specific ICD-10 code categories
python module_generator.py --diseases I20,I21,I22
# Generate up to 50 modules
python module_generator.py --limit 50
# Prioritize high-prevalence diseases (recommended)
python module_generator.py --prioritize
# Combine options for best results
python module_generator.py --diseases I,J,K --limit 100 --prioritize
```
## How It Works
1. The script loads the complete disease list from `disease_list.json`
2. It filters out diseases that already have modules
3. If `--prioritize` is enabled, it:
- Estimates the prevalence of each disease using a heuristic scoring system
- Prioritizes diseases based on common conditions, ICD-10 chapter, and name specificity
- Selects the highest-scoring diseases first
4. For each selected disease:
- Finds the most relevant existing module as a template (based on ICD-10 code)
- Sends a prompt to Claude with the disease details and template
- Validates the generated JSON
- Saves the new module to the appropriate location
- Updates the progress tracking file
## Configuration
- `CLAUDE_MODEL`: Set the Claude model to use (default: `claude-3-7-sonnet-20240229`)
- `SYNTHEA_ROOT`: Path to the Synthea root directory (auto-detected)
## Cost Estimation
The script uses Claude 3.7 Sonnet, which costs approximately:
- Input: $3 per million tokens
- Output: $15 per million tokens
A typical generation will use:
- ~10K input tokens (template + prompt)
- ~5K output tokens (generated module)
At this rate, generating 1,000 modules would cost approximately:
- Input: 10M tokens = $30
- Output: 5M tokens = $75
- Total: ~$105
## Logging
The script logs all activity to both the console and to `module_generation.log` in the current directory.
## Notes
- The script includes a 1-second delay between API calls to avoid rate limits
- Generated modules should be manually reviewed for quality and accuracy
- You may want to run the script incrementally (e.g., by disease category) to review results
- The script optimizes API usage by:
- Checking if a module already exists before generating (by filename or ICD-10 code)
- Only using Claude when a new module genuinely needs to be created
- Prioritizing high-prevalence diseases when using the `--prioritize` flag

View File

@@ -0,0 +1,732 @@
#!/usr/bin/env python3
"""
Module Generator for Synthea
This script automates the creation of new disease modules for Synthea based on
disease_list.json. It uses Claude 3.7 to generate appropriate JSON structures
for each disease, leveraging existing modules as templates.
Usage:
python module_generator.py [--diseases DISEASES] [--limit LIMIT]
Arguments:
--diseases DISEASES Comma-separated list of specific diseases to process (ICD-10 codes)
--limit LIMIT Maximum number of modules to generate (default: 10)
Example:
python src/main/python/run_module_generator.py --batch-size 3 --max-cost 10.0 --prioritize
"""
import os
import sys
import json
import glob
import re
import argparse
import time
import anthropic
import logging
from tqdm import tqdm
from typing import Dict, List, Any, Optional, Tuple
from dotenv import load_dotenv
# Load environment variables from .env file
load_dotenv()
# Configure logging
def setup_logging(log_file_path=None):
"""Configure logging to both file and console"""
if log_file_path is None:
log_file_path = "module_generation.log"
handlers = [
logging.FileHandler(log_file_path),
logging.StreamHandler(sys.stdout)
]
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=handlers
)
return logging.getLogger(__name__)
logger = logging.getLogger(__name__)
# Constants
SYNTHEA_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "../"))
DISEASE_LIST_PATH = os.path.join(SYNTHEA_ROOT, "src/main/resources/disease_list.json")
# Allow overriding MODULES_DIR with environment variable (for Docker)
MODULES_DIR = os.path.join(SYNTHEA_ROOT, "src/main/resources/modules")
if not os.path.exists(MODULES_DIR):
os.makedirs(MODULES_DIR, exist_ok=True)
logger.info(f"Created modules directory at {MODULES_DIR}")
PROGRESS_FILE = os.path.join(SYNTHEA_ROOT, "src/main/resources/disease_modules_progress.md")
TEMPLATES_DIR = os.path.join(SYNTHEA_ROOT, "src/main/resources/templates/modules")
# Check if directories exist, create if they don't
if not os.path.exists(TEMPLATES_DIR):
os.makedirs(TEMPLATES_DIR, exist_ok=True)
logger.info(f"Created templates directory at {TEMPLATES_DIR}")
# Check if progress file exists, create if it doesn't
if not os.path.exists(PROGRESS_FILE):
with open(PROGRESS_FILE, 'w') as f:
f.write("# Disease Module Progress\n\n")
f.write("## Completed Modules\n\n")
f.write("## Planned Modules\n\n")
logger.info(f"Created progress file at {PROGRESS_FILE}")
# Initialize Claude client (API key should be stored in ANTHROPIC_API_KEY environment variable)
api_key = os.getenv('ANTHROPIC_API_KEY')
if not api_key:
logger.error("ANTHROPIC_API_KEY environment variable is not set")
sys.exit(1)
# Create client without the proxies parameter which causes issues with older versions
client = anthropic.Client(api_key=api_key)
CLAUDE_MODEL = "claude-3-7-sonnet-20250219" # Updated to the current model version
MAX_TOKENS = 4096 # Maximum allowed tokens for Claude 3.7 Sonnet
def validate_condition_format(module_json):
"""Validate that conditions in the module follow Synthea's expected format"""
try:
module_dict = json.loads(module_json) if isinstance(module_json, str) else module_json
# Function to recursively check objects for improper condition structure
def check_conditions(obj):
issues = []
if isinstance(obj, dict):
# Check if this is a condition object with nested condition_type
if "condition" in obj and isinstance(obj["condition"], dict):
condition = obj["condition"]
# Look for the improper nested structure
if "condition_type" in condition and isinstance(condition["condition_type"], dict):
issues.append("Found nested condition_type in a condition object")
# Recursively check all dictionary values
for key, value in obj.items():
child_issues = check_conditions(value)
issues.extend(child_issues)
elif isinstance(obj, list):
# Recursively check all list items
for item in obj:
child_issues = check_conditions(item)
issues.extend(child_issues)
return issues
# Check the entire module
issues = check_conditions(module_dict)
return len(issues) == 0, issues
except Exception as e:
return False, [f"Validation error: {str(e)}"]
def load_disease_list() -> Dict[str, Dict[str, str]]:
"""Load the disease list from JSON file"""
try:
with open(DISEASE_LIST_PATH, 'r') as f:
diseases_list = json.load(f)
# Convert list to dict using disease_name as the key
diseases_dict = {}
for disease in diseases_list:
disease_name = disease.get('disease_name', '')
if disease_name:
# Create a new disease info dict with additional info
disease_info = {
'icd_10': disease.get('id', ''),
'snomed': disease.get('snomed', ''),
'ICD-10_name': disease.get('ICD-10_name', '')
}
diseases_dict[disease_name] = disease_info
return diseases_dict
except Exception as e:
logger.error(f"Error loading disease list: {e}")
sys.exit(1)
def get_existing_modules() -> List[str]:
"""Get list of existing module names (without extension)"""
module_files = glob.glob(os.path.join(MODULES_DIR, "*.json"))
return [os.path.splitext(os.path.basename(f))[0].lower() for f in module_files]
def find_most_relevant_module(disease_info: Dict[str, str], existing_modules: List[str]) -> str:
"""Find the most relevant existing module to use as a template"""
# First check if an icd code match exists
icd_code_prefix = disease_info.get("icd_10", "")[:3] # Get first 3 chars of ICD-10 code
# Look for modules that might relate to the same body system
related_modules = []
for module_path in glob.glob(os.path.join(MODULES_DIR, "*.json")):
with open(module_path, 'r') as f:
try:
content = f.read()
# Check if this module contains the same ICD-10 prefix
if f'"{icd_code_prefix}' in content:
related_modules.append(module_path)
except:
pass
if related_modules:
# Return the most complex related module (largest file size as a heuristic)
return max(related_modules, key=os.path.getsize)
# If no ICD match, return a default template based on disease type
if icd_code_prefix.startswith('I'): # Circulatory system
return os.path.join(MODULES_DIR, "hypertensive_renal_disease.json")
elif icd_code_prefix.startswith('J'): # Respiratory system
return os.path.join(MODULES_DIR, "asthma.json")
elif icd_code_prefix.startswith('K'): # Digestive system
return os.path.join(MODULES_DIR, "appendicitis.json")
else:
# Default to a simple template
return os.path.join(TEMPLATES_DIR, "prevalence.json")
def generate_module_with_claude(
disease_name: str,
disease_info: Dict[str, str],
template_path: str
) -> Tuple[str, int, int]:
"""Use Claude to generate a new module based on the template"""
# Load the template module
logger.info(f"Loading template module from {os.path.basename(template_path)}")
with open(template_path, 'r') as f:
template_content = f.read()
# Get template module name
template_name = os.path.splitext(os.path.basename(template_path))[0]
# Construct the prompt
prompt = f"""You are a medical expert and software developer tasked with creating disease modules for Synthea, an open-source synthetic patient generator.
TASK: Create a valid JSON module for the disease: "{disease_name}" (ICD-10 code: {disease_info.get('icd_10', 'Unknown')}).
CRITICAL: Your response MUST ONLY contain valid, parseable JSON that starts with {{ and ends with }}. No explanations, text, markdown formatting, or code blocks.
Disease Information:
- Name: {disease_name}
- ICD-10 Code: {disease_info.get('icd_10', 'Unknown')}
- SNOMED-CT Code: {disease_info.get('snomed', 'Unknown')}
I'm providing an example module structure based on {template_name}.json as a reference:
```json
{template_content}
```
Technical Requirements (MUST follow ALL of these):
1. JSON Format:
- Use valid JSON syntax with no errors
- No trailing commas
- All property names in double quotes
- Always add a "gmf_version": 2 field at the top level
- Check that all brackets and braces are properly matched
2. Module Structure:
- Include "name" field with {disease_name}
- Include "remarks" array with at least 3 items
- Include "states" object with complete set of disease states
- Add at least 2-3 reference URLs in the "remarks" section
- Every state needs a unique name and valid type (like "Initial", "Terminal", etc.)
- All transitions must be valid (direct_transition, distributed_transition, etc.)
3. Medical Content:
- Include accurate medical codes (SNOMED-CT, ICD-10, LOINC, RxNorm)
- Model realistic disease prevalence based on age, gender, race
- Include relevant symptoms, diagnostic criteria, treatments
- Only include states that make clinical sense for this specific disease
4. CRITICAL CONDITION STRUCTURE REQUIREMENTS:
- In conditional statements, the 'condition_type' MUST be a top-level key within the condition object
- INCORRECT: "condition": {"condition_type": {"nested": "value"}, "name": "SomeState"}
- CORRECT: "condition": {"condition_type": "PriorState", "name": "SomeState"}
- Common condition types: "Age", "Gender", "Race", "Attribute", "And", "Or", "Not", "PriorState", "Active Condition"
- For PriorState conditions, use: {"condition_type": "PriorState", "name": "StateName"}
- For attribute checks, use: {"condition_type": "Attribute", "attribute": "attr_name", "operator": "==", "value": true}
IMPORTANT REMINDER: Respond with ONLY valid JSON, not explanations. The entire response should be a single JSON object that can be directly parsed.
"""
# Request generation from Claude using older API version 0.8.1
logger.info(f"Sending request to Claude API for '{disease_name}'")
try:
# Use the Anthropic API with older syntax
response = client.completion(
model=CLAUDE_MODEL,
max_tokens_to_sample=MAX_TOKENS,
temperature=0.1, # Lower temperature for more consistent, predicable output
prompt=f"\n\nHuman: {prompt}\n\nAssistant: ",
stream=False
)
# For v0.8.1, the response is a completion object with a completion property
content = response.completion
# Remove any markdown code block indicators
content = re.sub(r'^```json\s*', '', content)
content = re.sub(r'^```\s*', '', content)
content = re.sub(r'```$', '', content)
# Log content type for debugging
logger.debug(f"Content type: {type(content)}")
# Ensure content is string
if not isinstance(content, str):
content = content.decode('utf-8') if hasattr(content, 'decode') else str(content)
# Estimate token usage - we don't get this directly with streaming
# Rough estimate: 1 token ≈ 4 characters
input_token_estimate = len(prompt) // 4
output_token_estimate = len(content) // 4
# Log estimated token usage
logger.info(f"API call for '{disease_name}' - Estimated input tokens: {input_token_estimate}, "
f"Estimated output tokens: {output_token_estimate}")
# Validate and format JSON
try:
# Parse and format with Python's built-in json module
parsed = json.loads(content)
# Validate condition structure
valid, issues = validate_condition_format(parsed)
if not valid:
logger.warning(f"Generated module for {disease_name} has condition structure issues: {issues}")
logger.warning("Requesting regeneration with corrected instructions...")
# Add more specific instructions for the retry
retry_prompt = prompt + "\n\nPLEASE FIX THESE ISSUES: " + ", ".join(issues)
retry_prompt += "\n\nREMINDER: All condition objects must have 'condition_type' as a top-level key, NOT nested."
# Call Claude again with the refined prompt using older API
logger.info(f"Retrying generation for '{disease_name}' with specific instructions about issues")
retry_response = client.completion(
model=CLAUDE_MODEL,
max_tokens_to_sample=MAX_TOKENS,
temperature=0.1,
prompt=f"\n\nHuman: {retry_prompt}\n\nAssistant: ",
stream=False
)
# For v0.8.1, the response is a completion object with a completion property
retry_content = retry_response.completion
# Remove any markdown code block indicators
retry_content = re.sub(r'^```json\s*', '', retry_content)
retry_content = re.sub(r'^```\s*', '', retry_content)
retry_content = re.sub(r'```$', '', retry_content)
# Try to parse the retry response
try:
retry_parsed = json.loads(retry_content)
# Validate the retry response
retry_valid, retry_issues = validate_condition_format(retry_parsed)
if not retry_valid and args.strict:
logger.error(f"Failed to fix condition structure issues after retry: {retry_issues}")
raise ValueError(f"Module format validation failed: {retry_issues}")
elif not retry_valid:
logger.warning(f"Retry still has issues, but proceeding due to non-strict mode: {retry_issues}")
# Use the retry response even with issues
formatted_json = json.dumps(retry_parsed, indent=2)
else:
# Successfully fixed the issues
logger.info(f"Successfully fixed condition structure issues for '{disease_name}'")
formatted_json = json.dumps(retry_parsed, indent=2)
except json.JSONDecodeError as e:
logger.error(f"Retry response is still not valid JSON: {e}")
if args.strict:
raise ValueError(f"Failed to generate valid JSON after retry: {e}")
else:
# Fall back to the original response in non-strict mode
logger.warning("Using original response despite issues (non-strict mode)")
formatted_json = json.dumps(parsed, indent=2)
else:
# Original response was valid
formatted_json = json.dumps(parsed, indent=2)
logger.info(f"Successfully generated valid JSON for '{disease_name}'")
return formatted_json, input_token_estimate, output_token_estimate
except json.JSONDecodeError as e:
logger.error(f"Generated content is not valid JSON: {e}")
logger.debug(f"Generated content: {content[:500]}...") # Log first 500 chars for debugging
# Try different extraction methods for the JSON
extraction_attempts = [
# Method 1: Find content between JSON code block markers
re.search(r'```json([\s\S]*?)```', content),
# Method 2: Find content between code block markers
re.search(r'```([\s\S]*?)```', content),
# Method 3: Find content between curly braces
re.search(r'({[\s\S]*})', content),
# Method 4: Find anything that looks like JSON starting with {
re.search(r'({.*})', content, re.DOTALL)
]
for attempt in extraction_attempts:
if attempt:
try:
extracted_content = attempt.group(1).strip()
# Add missing braces and fix incomplete JSON structures
# First clean up the JSON to remove any trailing commas before closing brackets
extracted_content = re.sub(r',\s*}', '}', extracted_content)
extracted_content = re.sub(r',\s*]', ']', extracted_content)
# Count opening and closing braces to detect missing ones
open_braces = extracted_content.count('{')
close_braces = extracted_content.count('}')
open_brackets = extracted_content.count('[')
close_brackets = extracted_content.count(']')
# Add missing braces or brackets if needed
if open_braces > close_braces:
extracted_content += '}' * (open_braces - close_braces)
logger.info(f"Added {open_braces - close_braces} missing closing braces")
elif close_braces > open_braces:
# Remove excess closing braces
for _ in range(close_braces - open_braces):
extracted_content = extracted_content.rstrip().rstrip('}') + '}'
logger.info(f"Removed {close_braces - open_braces} excess closing braces")
if open_brackets > close_brackets:
extracted_content += ']' * (open_brackets - close_brackets)
logger.info(f"Added {open_brackets - close_brackets} missing closing brackets")
elif close_brackets > open_brackets:
# Remove excess closing brackets
for _ in range(close_brackets - open_brackets):
last_bracket = extracted_content.rfind(']')
if last_bracket >= 0:
extracted_content = extracted_content[:last_bracket] + extracted_content[last_bracket+1:]
logger.info(f"Removed {close_brackets - open_brackets} excess closing brackets")
# Parse and format with Python's json module
parsed = json.loads(extracted_content)
# Format with Python's json module
formatted_json = json.dumps(parsed, indent=2)
logger.info(f"Successfully extracted valid JSON for '{disease_name}' after extraction attempt")
return formatted_json, input_token_estimate, output_token_estimate
except json.JSONDecodeError:
continue
# If all attempts fail, try manual repair of common issues
try:
# Remove any triple backticks
cleaned = re.sub(r'```.*?```', '', content, flags=re.DOTALL)
# Remove any backticks
cleaned = re.sub(r'`', '', cleaned)
# Ensure proper quotes (replace single quotes with double quotes where needed)
cleaned = re.sub(r"'([^']*?)':", r'"\1":', cleaned)
# Fix trailing commas before closing brackets
cleaned = re.sub(r',\s*}', '}', cleaned)
cleaned = re.sub(r',\s*]', ']', cleaned)
# Find the module content between { }
module_match = re.search(r'({[\s\S]*})', cleaned)
if module_match:
module_json = module_match.group(1)
# Parse and format with Python's json module
parsed = json.loads(module_json)
# Format with Python's json module
formatted_json = json.dumps(parsed, indent=2)
logger.info(f"Successfully repaired and extracted JSON for '{disease_name}'")
return formatted_json, input_token_estimate, output_token_estimate
except Exception as repair_error:
logger.error(f"Failed to repair JSON: {repair_error}")
# Log a sample of the problematic content for debugging
debug_sample = content[:min(500, len(content))] + "..." if len(content) > 500 else content
logger.error(f"Could not extract valid JSON from Claude's response for '{disease_name}'")
logger.error(f"Response sample (first 500 chars): {debug_sample}")
logger.error(f"Full content length: {len(content)} characters")
raise ValueError("Could not extract valid JSON from Claude's response")
except Exception as e:
logger.error(f"Error generating module with Claude: {e}")
raise
def update_progress_file(disease_name: str, icd_code: str) -> None:
"""Update the progress tracking file with the newly created module"""
try:
with open(PROGRESS_FILE, 'r') as f:
content = f.readlines()
# Find the "Completed Modules" section and add the new module
for i, line in enumerate(content):
if line.startswith('## Completed Modules'):
# Count existing modules to determine next number
count = 0
for j in range(i+1, len(content)):
if content[j].strip() and content[j][0].isdigit():
count += 1
elif content[j].startswith('##'):
break
# Insert new module entry
content.insert(i+1+count, f"{count+1}. {disease_name} ({icd_code}) - Generated by module_generator.py\n")
break
with open(PROGRESS_FILE, 'w') as f:
f.writelines(content)
except Exception as e:
logger.error(f"Error updating progress file: {e}")
def normalize_filename(disease_name: str) -> str:
"""Convert disease name to a valid filename"""
# Replace spaces and special characters with underscores
filename = re.sub(r'[^a-zA-Z0-9]', '_', disease_name.lower())
# Remove consecutive underscores
filename = re.sub(r'_+', '_', filename)
# Remove leading/trailing underscores
filename = filename.strip('_')
return filename
def get_existing_module_path(disease_name: str, disease_info: Dict[str, str]) -> Optional[str]:
"""Check if a module for this disease already exists and return its path"""
# Method 1: Check by normalized filename
normalized_name = normalize_filename(disease_name)
candidate_path = os.path.join(MODULES_DIR, f"{normalized_name}.json")
if os.path.exists(candidate_path):
return candidate_path
# Method 2: Check by ICD-10 code in existing modules
icd_code = disease_info.get('icd_10', '')
if icd_code:
for module_path in glob.glob(os.path.join(MODULES_DIR, "*.json")):
with open(module_path, 'r') as f:
try:
content = f.read()
# Check for exact ICD-10 code match
if f'"code": "{icd_code}"' in content:
return module_path
except:
pass
# No existing module found
return None
def estimate_disease_prevalence(disease_name: str, icd_code: str) -> float:
"""Estimate disease prevalence for prioritization (higher = more prevalent)"""
# This is a simple heuristic - you could replace with actual prevalence data if available
# Some common conditions tend to have higher prevalence
common_conditions = [
"hypertension", "diabetes", "arthritis", "asthma", "depression",
"anxiety", "obesity", "cancer", "heart", "copd", "stroke", "pneumonia",
"bronchitis", "influenza", "infection", "pain", "fracture"
]
score = 1.0
# Check if it contains common condition keywords
name_lower = disease_name.lower()
for condition in common_conditions:
if condition in name_lower:
score += 2.0
break
# ICD-10 chapter weighting (approximate prevalence by chapter)
if icd_code.startswith('I'): # Circulatory system
score += 5.0
elif icd_code.startswith('J'): # Respiratory system
score += 4.0
elif icd_code.startswith('K'): # Digestive system
score += 3.5
elif icd_code.startswith('M'): # Musculoskeletal system
score += 3.0
elif icd_code.startswith('E'): # Endocrine, nutritional and metabolic diseases
score += 4.0
elif icd_code.startswith('F'): # Mental and behavioral disorders
score += 3.5
# Prefer shorter, more specific disease names (likely more common conditions)
if len(disease_name.split()) <= 3:
score += 1.0
return score
def main():
parser = argparse.ArgumentParser(description='Generate Synthea disease modules')
parser.add_argument('--diseases', type=str, help='Comma-separated list of ICD-10 codes to process')
parser.add_argument('--limit', type=int, default=10, help='Maximum number of modules to generate')
parser.add_argument('--prioritize', action='store_true', help='Prioritize high-prevalence diseases')
parser.add_argument('--log-file', type=str, help='Path to log file for token usage tracking')
parser.add_argument('--strict', action='store_true',
help='Fail immediately on validation errors instead of trying to fix them')
# Add support for direct disease generation
parser.add_argument('--disease', type=str, help='Single disease name to generate')
parser.add_argument('--output', type=str, help='Output path for the generated module')
args = parser.parse_args()
# Setup logging with custom log file if specified
global logger
if args.log_file:
logger = setup_logging(args.log_file)
else:
logger = setup_logging()
# Check if we're operating in direct mode (single disease)
if args.disease and args.output:
try:
logger.info(f"Generating module for single disease: {args.disease}")
# Create a simple disease info dictionary
disease_info = {
'icd_10': '', # Empty since we don't have this info
'snomed': '', # Empty since we don't have this info
'ICD-10_name': args.disease
}
# Try to find a relevant template
templates = glob.glob(os.path.join(TEMPLATES_DIR, "*.json"))
if templates:
template_path = templates[0] # Use the first template found
else:
# Use a simple default template if none found
logger.warning("No template found, using a minimal default")
template_path = os.path.join(MODULES_DIR, "appendicitis.json")
if not os.path.exists(template_path):
raise ValueError(f"Cannot find any suitable template for generation")
# Generate the module
module_content, _, _ = generate_module_with_claude(args.disease, disease_info, template_path)
# Save the module to the specified output path
with open(args.output, 'w') as f:
f.write(module_content)
logger.info(f"Successfully generated module for {args.disease}")
print(f"Successfully generated module for {args.disease}")
return
except Exception as e:
logger.error(f"Error generating single disease module: {e}")
print(f"Error: {e}")
sys.exit(1)
# Load disease list
all_diseases = load_disease_list()
logger.info(f"Loaded {len(all_diseases)} diseases from disease_list.json")
# Get existing modules
existing_modules = get_existing_modules()
logger.info(f"Found {len(existing_modules)} existing modules")
# Filter diseases to process
if args.diseases:
disease_codes = [code.strip() for code in args.diseases.split(',')]
to_process = {name: info for name, info in all_diseases.items()
if info.get('icd_10', '').split('.')[0] in disease_codes}
logger.info(f"Filtered to {len(to_process)} diseases matching specified codes")
else:
# Process all diseases up to the limit
to_process = all_diseases
# Only include diseases that don't already have modules by filename
# (We'll do a more thorough check later with get_existing_module_path)
diseases_to_create = {}
candidate_diseases = []
for name, info in to_process.items():
normalized_name = normalize_filename(name)
if normalized_name not in existing_modules:
if args.prioritize:
# Add to candidates for prioritization
icd_code = info.get('icd_10', '').split('.')[0]
prevalence_score = estimate_disease_prevalence(name, icd_code)
candidate_diseases.append((name, info, prevalence_score))
else:
diseases_to_create[name] = info
# Respect the limit for non-prioritized mode
if len(diseases_to_create) >= args.limit:
break
# If prioritizing, sort by estimated prevalence and take top N
if args.prioritize and candidate_diseases:
logger.info("Prioritizing diseases by estimated prevalence")
candidate_diseases.sort(key=lambda x: x[2], reverse=True)
# Log top candidates for transparency
logger.info("Top candidates by estimated prevalence:")
for i, (name, info, score) in enumerate(candidate_diseases[:min(10, len(candidate_diseases))]):
logger.info(f" {i+1}. {name} (ICD-10: {info.get('icd_10', 'Unknown')}) - Score: {score:.2f}")
# Select top N diseases
for name, info, _ in candidate_diseases[:args.limit]:
diseases_to_create[name] = info
logger.info(f"Will generate modules for {len(diseases_to_create)} diseases")
# Generate modules
for disease_name, disease_info in tqdm(diseases_to_create.items(), desc="Generating modules"):
try:
# First check if module already exists - no need to use LLM if it does
existing_module_path = get_existing_module_path(disease_name, disease_info)
if existing_module_path:
# Module already exists, just copy it
logger.info(f"Module for {disease_name} already exists at {existing_module_path}")
# Read existing module
with open(existing_module_path, 'r') as f:
module_content = f.read()
# Save to normalized filename if different from existing path
filename = normalize_filename(disease_name) + ".json"
output_path = os.path.join(MODULES_DIR, filename)
if output_path != existing_module_path:
with open(output_path, 'w') as f:
f.write(module_content)
logger.info(f"Copied existing module to {output_path}")
else:
logger.info(f"Existing module already has correct filename")
# Update progress file
icd_code = disease_info.get('icd_10', 'Unknown')
update_progress_file(disease_name, icd_code)
else:
# No existing module, generate with Claude
# Find best template
template_path = find_most_relevant_module(disease_info, existing_modules)
logger.info(f"Using {os.path.basename(template_path)} as template for {disease_name}")
# Generate module
module_content, input_tokens, output_tokens = generate_module_with_claude(disease_name, disease_info, template_path)
# Save module
filename = normalize_filename(disease_name) + ".json"
output_path = os.path.join(MODULES_DIR, filename)
with open(output_path, 'w') as f:
f.write(module_content)
logger.info(f"Successfully created module for {disease_name}")
# Update progress file
icd_code = disease_info.get('icd_10', 'Unknown')
update_progress_file(disease_name, icd_code)
# Sleep to avoid hitting API rate limits
time.sleep(1)
except Exception as e:
logger.error(f"Failed to generate module for {disease_name}: {e}")
logger.info("Module generation complete")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,478 @@
#!/usr/bin/env python3
"""
Disease Module Generator Loop for Synthea
This script runs the module_generator.py script in a loop to generate
modules for diseases in disease_list.json that don't have modules yet.
Usage:
python run_module_generator.py [--batch-size BATCH_SIZE] [--max-modules MAX_MODULES]
Arguments:
--batch-size BATCH_SIZE Number of modules to generate in each batch (default: 5)
--max-modules MAX_MODULES Maximum total number of modules to generate (default: no limit)
--prioritize Prioritize high-prevalence diseases first
--max-cost MAX_COST Maximum cost in USD to spend (default: no limit)
--strict Fail immediately on module validation errors instead of trying to fix them
"""
import os
import sys
import json
import subprocess
import argparse
import time
import logging
import anthropic
import re
from pathlib import Path
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler("module_generation_runner.log"),
logging.StreamHandler(sys.stdout)
]
)
logger = logging.getLogger(__name__)
# Constants
SYNTHEA_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../.."))
# Support both Docker (/app) and local development paths
if os.path.exists("/app/src/main/resources/disease_list.json"):
DISEASE_LIST_PATH = "/app/src/main/resources/disease_list.json"
MODULES_DIR = "/app/src/main/resources/modules"
LOG_FILE_PATH = "/app/module_generation_runner.log"
else:
DISEASE_LIST_PATH = os.path.join(SYNTHEA_ROOT, "src/main/resources/disease_list.json")
MODULES_DIR = os.path.join(SYNTHEA_ROOT, "src/main/resources/modules")
LOG_FILE_PATH = os.path.join(SYNTHEA_ROOT, "module_generation_runner.log")
MODULE_GENERATOR_PATH = os.path.join(os.path.dirname(__file__), "module_generator.py")
# API costs - Claude 3.7 Sonnet (as of March 2025)
# These are approximate costs based on current pricing
CLAUDE_INPUT_COST_PER_1K_TOKENS = 0.003 # $0.003 per 1K input tokens
CLAUDE_OUTPUT_COST_PER_1K_TOKENS = 0.015 # $0.015 per 1K output tokens
# Initialize cost tracking
total_input_tokens = 0
total_output_tokens = 0
total_cost_usd = 0.0
def count_existing_modules():
"""Count the number of modules already created"""
module_files = list(Path(MODULES_DIR).glob("*.json"))
return len(module_files)
def count_remaining_diseases():
"""Count how many diseases in disease_list.json don't have modules yet"""
# Load the disease list
with open(DISEASE_LIST_PATH, 'r') as f:
diseases = json.load(f)
# Get existing module names
existing_modules = set()
for module_file in Path(MODULES_DIR).glob("*.json"):
module_name = module_file.stem.lower()
existing_modules.add(module_name)
# Count diseases that don't have modules
remaining = 0
for disease in diseases:
# Extract disease name from the disease object
disease_name = disease['disease_name']
# Convert disease name to module filename format
module_name = disease_name.lower()
module_name = ''.join(c if c.isalnum() else '_' for c in module_name)
module_name = module_name.strip('_')
# Replace consecutive underscores with a single one
while '__' in module_name:
module_name = module_name.replace('__', '_')
if module_name not in existing_modules:
remaining += 1
return remaining, len(diseases)
def parse_api_usage(log_content):
"""Parse API usage stats from log content"""
global total_input_tokens, total_output_tokens, total_cost_usd
# Look for token counts in the log - using the updated pattern from the logs
# This matches the format: "Estimated input tokens: 7031, Estimated output tokens: 3225"
input_token_matches = re.findall(r'Estimated input tokens: (\d+)', log_content)
output_token_matches = re.findall(r'Estimated output tokens: (\d+)', log_content)
batch_input_tokens = sum(int(count) for count in input_token_matches)
batch_output_tokens = sum(int(count) for count in output_token_matches)
# Calculate cost for this batch
batch_input_cost = batch_input_tokens * CLAUDE_INPUT_COST_PER_1K_TOKENS / 1000
batch_output_cost = batch_output_tokens * CLAUDE_OUTPUT_COST_PER_1K_TOKENS / 1000
batch_total_cost = batch_input_cost + batch_output_cost
# Update totals
total_input_tokens += batch_input_tokens
total_output_tokens += batch_output_tokens
total_cost_usd += batch_total_cost
# Log the token counts found for debugging
logger.info(f"Found token counts in log - Input: {input_token_matches}, Output: {output_token_matches}")
return batch_input_tokens, batch_output_tokens, batch_total_cost
def run_module_generator(batch_size=5, prioritize=False, timeout=600, strict=False):
"""Run the module generator script with the specified batch size"""
try:
# Create a unique log file for this batch to capture token usage
batch_log_file = f"module_generator_batch_{int(time.time())}.log"
cmd = [
sys.executable,
MODULE_GENERATOR_PATH,
'--limit', str(batch_size),
'--log-file', batch_log_file
]
if prioritize:
cmd.append('--prioritize')
if strict:
cmd.append('--strict')
logger.info(f"Running command: {' '.join(cmd)}")
print(f"\n[INFO] Starting batch, generating up to {batch_size} modules...")
# Use timeout to prevent indefinite hanging
try:
result = subprocess.run(cmd, capture_output=True, text=True, check=True, timeout=timeout)
success = True
except subprocess.TimeoutExpired:
logger.error(f"Module generator timed out after {timeout} seconds")
print(f"\n[ERROR] Process timed out after {timeout} seconds!")
success = False
result = None
# Process output only if the command completed successfully
if success and result:
# Log output
if result.stdout:
for line in result.stdout.splitlines():
logger.info(f"Generator output: {line}")
# Print progress-related lines directly to console
if "Generated module for" in line or "modules complete" in line:
print(f"[PROGRESS] {line}")
# Check if any errors
if result.stderr:
for line in result.stderr.splitlines():
if "Error" in line or "Exception" in line:
logger.error(f"Generator error: {line}")
print(f"[ERROR] {line}")
else:
logger.info(f"Generator message: {line}")
# Parse token usage from the log file
if os.path.exists(batch_log_file):
with open(batch_log_file, 'r') as f:
log_content = f.read()
# Parse usage statistics
batch_input_tokens, batch_output_tokens, batch_cost = parse_api_usage(log_content)
# Log usage for this batch
logger.info(f"Batch API Usage - Input tokens: {batch_input_tokens:,}, "
f"Output tokens: {batch_output_tokens:,}, Cost: ${batch_cost:.4f}")
logger.info(f"Total API Usage - Input tokens: {total_input_tokens:,}, "
f"Output tokens: {total_output_tokens:,}, Total Cost: ${total_cost_usd:.4f}")
# Print to console in a prominent way
print("\n" + "="*80)
print(f"BATCH API USAGE - Cost: ${batch_cost:.4f}")
print(f"TOTAL API USAGE - Cost: ${total_cost_usd:.4f}")
print("="*80 + "\n")
# Clean up batch log file
try:
os.remove(batch_log_file)
except:
pass
# Count created files to verify success
if os.path.exists(batch_log_file):
with open(batch_log_file, 'r') as f:
log_content = f.read()
modules_created = log_content.count("Successfully created module for")
if modules_created > 0:
print(f"[SUCCESS] Created {modules_created} module(s) in this batch")
# Clean up even if processing didn't complete
try:
os.remove(batch_log_file)
except:
pass
return success
except subprocess.CalledProcessError as e:
logger.error(f"Module generator failed with exit code {e.returncode}")
logger.error(f"Error output: {e.stderr}")
print(f"[ERROR] Module generator process failed with exit code {e.returncode}")
return False
except Exception as e:
logger.error(f"Failed to run module generator: {e}")
print(f"[ERROR] Failed to run module generator: {e}")
return False
def validate_and_fix_existing_modules(strict=False):
"""Check all existing modules for JSON validity and fix if needed"""
print("Validating existing modules...")
if strict:
print("Running in strict mode - modules will NOT be fixed automatically")
fixed_count = 0
module_files = list(Path(MODULES_DIR).glob("*.json"))
# First, show a summary of all modules
print(f"Found {len(module_files)} module files")
invalid_modules = []
# Check all modules for validity
for module_path in module_files:
try:
with open(module_path, 'r') as f:
content = f.read()
# Try to parse the JSON
try:
json.loads(content)
# If it parses successfully, all good
continue
except json.JSONDecodeError as e:
invalid_modules.append((module_path, e))
print(f"⚠️ Invalid JSON found in {module_path.name}: {e}")
except Exception as e:
print(f"Error processing {module_path}: {e}")
if not invalid_modules:
print("✅ All modules are valid JSON")
return 0
print(f"\nFound {len(invalid_modules)} invalid module(s) to fix")
# Now fix the invalid modules
for module_path, error in invalid_modules:
try:
print(f"\nAttempting to fix {module_path.name}...")
if strict:
print(f"❌ Module {module_path.name} has validation issues that must be fixed manually")
continue # Skip fixing in strict mode
with open(module_path, 'r') as f:
content = f.read()
# Try to fix common issues
fixed_content = content
# Fix trailing commas
fixed_content = re.sub(r',\s*}', '}', fixed_content)
fixed_content = re.sub(r',\s*]', ']', fixed_content)
# Check for incomplete states section
if '"states": {' in fixed_content:
# Make sure it has a proper closing brace
states_match = re.search(r'"states":\s*{(.*)}(?=\s*,|\s*})', fixed_content, re.DOTALL)
if not states_match and '"states": {' in fixed_content:
print(" - Module appears to have an incomplete states section")
# Find last complete state definition
last_state_end = None
state_pattern = re.compile(r'("[^"]+"\s*:\s*{[^{]*?}),?', re.DOTALL)
for match in state_pattern.finditer(fixed_content, fixed_content.find('"states": {') + 12):
last_state_end = match.end()
if last_state_end:
# Add closing brace after the last valid state
fixed_content = fixed_content[:last_state_end] + '\n }\n }' + fixed_content[last_state_end:]
print(" - Added closing braces for states section")
# Fix missing/unbalanced braces
open_braces = fixed_content.count('{')
close_braces = fixed_content.count('}')
if open_braces > close_braces:
fixed_content += '}' * (open_braces - close_braces)
print(f" - Added {open_braces - close_braces} missing closing braces")
elif close_braces > open_braces:
for _ in range(close_braces - open_braces):
fixed_content = fixed_content.rstrip().rstrip('}') + '}'
print(f" - Removed {close_braces - open_braces} excess closing braces")
# Try to parse the fixed content
try:
parsed_json = json.loads(fixed_content)
# Check if it has all required elements
if 'name' not in parsed_json:
print(" - Warning: Module missing 'name' field")
if 'states' not in parsed_json:
print(" - Warning: Module missing 'states' field")
if 'gmf_version' not in parsed_json:
print(" - Adding missing gmf_version field")
# Make sure we have a proper JSON object
if fixed_content.rstrip().endswith('}'):
# Add the gmf_version before the final brace
fixed_content = fixed_content.rstrip().rstrip('}') + ',\n "gmf_version": 2\n}'
# Backup the original file
backup_path = str(module_path) + '.bak'
import shutil
shutil.copy2(str(module_path), backup_path)
# Write the fixed content
with open(module_path, 'w') as f:
f.write(fixed_content)
print(f"✅ Fixed module {module_path.name}")
fixed_count += 1
except json.JSONDecodeError as e:
print(f"❌ Could not fix module {module_path.name}: {e}")
except Exception as e:
print(f"Error processing {module_path}: {e}")
print(f"\nValidation complete. Fixed {fixed_count} of {len(invalid_modules)} invalid modules.")
return fixed_count
def main():
parser = argparse.ArgumentParser(description='Run the module generator in a loop')
parser.add_argument('--batch-size', type=int, default=5,
help='Number of modules to generate in each batch (default: 5)')
parser.add_argument('--max-modules', type=int, default=None,
help='Maximum total number of modules to generate (default: no limit)')
parser.add_argument('--max-batches', type=int, default=None,
help='Maximum number of batches to run (default: no limit)')
parser.add_argument('--prioritize', action='store_true',
help='Prioritize high-prevalence diseases first')
parser.add_argument('--max-cost', type=float, default=None,
help='Maximum cost in USD to spend (default: no limit)')
parser.add_argument('--timeout', type=int, default=600,
help='Timeout in seconds for each batch process (default: 600)')
parser.add_argument('--fix-modules', action='store_true',
help='Check and fix existing modules for JSON validity')
parser.add_argument('--strict', action='store_true',
help='Fail immediately on module validation errors instead of trying to fix them')
args = parser.parse_args()
# If fix-modules flag is set, validate and fix existing modules
if args.fix_modules:
validate_and_fix_existing_modules(strict=args.strict)
return
# Initial counts
initial_modules = count_existing_modules()
initial_remaining, total_diseases = count_remaining_diseases()
logger.info(f"Starting module generation loop")
logger.info(f"Currently have {initial_modules} modules")
logger.info(f"Remaining diseases without modules: {initial_remaining} of {total_diseases}")
# Set up counters
modules_created = 0
batch_count = 0
# Loop until we've hit our maximum or there are no more diseases to process
while True:
# Break if we've reached the maximum modules to generate
if args.max_modules is not None and modules_created >= args.max_modules:
logger.info(f"Reached maximum modules limit ({args.max_modules})")
print(f"\n{'!'*80}")
print(f"MODULE LIMIT REACHED: {modules_created} >= {args.max_modules}")
print(f"{'!'*80}\n")
break
# Break if we've reached the maximum batches
if args.max_batches is not None and batch_count >= args.max_batches:
logger.info(f"Reached maximum batch limit ({args.max_batches})")
print(f"\n{'!'*80}")
print(f"BATCH LIMIT REACHED: {batch_count} >= {args.max_batches}")
print(f"{'!'*80}\n")
break
# Break if we've reached the maximum cost
if args.max_cost is not None and total_cost_usd >= args.max_cost:
logger.info(f"Reached maximum cost limit (${args.max_cost:.2f})")
print(f"\n{'!'*80}")
print(f"COST LIMIT REACHED: ${total_cost_usd:.4f} >= ${args.max_cost:.2f}")
print(f"{'!'*80}\n")
break
# Count how many modules we need to generate in this batch
if args.max_modules is not None:
# Adjust batch size if we're near the maximum
current_batch_size = min(args.batch_size, args.max_modules - modules_created)
else:
current_batch_size = args.batch_size
if current_batch_size <= 0:
logger.info("No more modules to generate in this batch")
print("[INFO] No more modules to generate (reached limit)")
break
# Run the generator for this batch
batch_count += 1
logger.info(f"Starting batch {batch_count} (generating up to {current_batch_size} modules)")
# Run the generator
success = run_module_generator(
batch_size=current_batch_size,
prioritize=args.prioritize,
timeout=args.timeout,
strict=args.strict
)
if not success:
logger.error(f"Batch {batch_count} failed, stopping")
print(f"[ERROR] Batch {batch_count} failed, stopping")
break
# Count how many modules we've created so far
new_module_count = count_existing_modules()
modules_created = new_module_count - initial_modules
# Count remaining diseases
remaining_diseases, _ = count_remaining_diseases()
logger.info(f"Completed batch {batch_count}")
logger.info(f"Total modules created: {modules_created}")
logger.info(f"Remaining diseases without modules: {remaining_diseases}")
print(f"[STATUS] Batch {batch_count} complete")
print(f"[STATUS] Total modules created: {modules_created}")
print(f"[STATUS] Remaining diseases: {remaining_diseases} of {total_diseases}")
# Break if no diseases left
if remaining_diseases <= 0:
logger.info("All diseases have modules now, finished!")
print("[SUCCESS] All diseases have modules now, finished!")
break
# Sleep briefly between batches to avoid system overload
time.sleep(2)
# Final status
logger.info(f"Module generation complete!")
logger.info(f"Started with {initial_modules} modules, now have {count_existing_modules()}")
logger.info(f"Created {modules_created} new modules in {batch_count} batches")
remaining, total = count_remaining_diseases()
logger.info(f"Remaining diseases without modules: {remaining} of {total}")
if __name__ == "__main__":
main()

51
nextflow.config Normal file
View File

@@ -0,0 +1,51 @@
// Nextflow configuration file
manifest {
description = 'Synthea Module Generator Pipeline'
}
// Load parameters from params.json
def paramsJson = new File("$baseDir/params.json").text
def paramsData = new groovy.json.JsonSlurper().parseText(paramsJson)
// Merge with defaults
params {
disease_name = paramsData.disease_name
modules_dir = paramsData.modules_dir ?: "/Users/richman/workspace/synthea-alldiseases/modules"
output_dir = paramsData.output_dir ?: "output"
population = paramsData.population ?: 100
gender = paramsData.gender ?: 0.5
min_age = paramsData.min_age ?: 0
max_age = paramsData.max_age ?: 90
seed = paramsData.seed
generate_patients = paramsData.generate_patients ?: true
publish_dir = paramsData.publish_dir ?: "published_output"
// Additional params
max_cost = 5.0
timeout = 300
anthropic_api_key = null
batch_size = 1
help = false
}
docker {
enabled = true
runOptions = "-v $baseDir/$params.modules_dir:/app/src/main/resources/modules -v $baseDir/src/main/python:/app/src/main/python -v $baseDir/src/main/resources:/app/src/main/resources -v $baseDir/.env:/app/.env"
}
process {
container = 'synthea-module-generator'
containerOptions = "-e MODULES_DIR=/app/src/main/resources/modules -e PYTHONPATH=/app -e ANTHROPIC_API_KEY=${params.anthropic_api_key}"
}
trace {
enabled = true
overwrite = true
file = "$baseDir/trace.txt"
}
profiles {
standard {
process.executor = 'local'
}
}

14
params.json Normal file
View File

@@ -0,0 +1,14 @@
{
"disease_name": "Parkinson's Disease",
"modules_dir": "modules",
"output_dir": "output",
"generate_patients": true,
"population": 10,
"gender": 0.5,
"min_age": 0,
"max_age": 90,
"analyze_patient_data": false,
"report_format": "html",
"force_generate": false,
"publish_dir": "published_output"
}

14
scripts/.nextflow.log Normal file
View File

@@ -0,0 +1,14 @@
Mar-20 17:36:01.178 [main] DEBUG nextflow.cli.Launcher - $> nextflow run main.nf --disease_name Migraine --generate_patients true --population 100 --gender 0.6 --modules_dir modules
Mar-20 17:36:01.428 [main] DEBUG nextflow.cli.CmdRun - N E X T F L O W ~ version 24.10.5
Mar-20 17:36:01.492 [main] DEBUG nextflow.plugin.PluginsFacade - Setting up plugin manager > mode=prod; embedded=false; plugins-dir=/Users/richman/.nextflow/plugins; core-plugins: nf-amazon@2.9.2,nf-azure@1.10.2,nf-cloudcache@0.4.2,nf-codecommit@0.2.2,nf-console@1.1.4,nf-google@1.15.4,nf-tower@1.9.3,nf-wave@1.7.4
Mar-20 17:36:01.528 [main] INFO o.pf4j.DefaultPluginStatusProvider - Enabled plugins: []
Mar-20 17:36:01.529 [main] INFO o.pf4j.DefaultPluginStatusProvider - Disabled plugins: []
Mar-20 17:36:01.538 [main] INFO org.pf4j.DefaultPluginManager - PF4J version 3.12.0 in 'deployment' mode
Mar-20 17:36:01.559 [main] INFO org.pf4j.AbstractPluginManager - No plugins
Mar-20 17:36:01.590 [main] DEBUG nextflow.scm.ProviderConfig - Using SCM config path: /Users/richman/.nextflow/scm
Mar-20 17:36:01.624 [main] DEBUG nextflow.cli.Launcher - Operation aborted
nextflow.exception.AbortOperationException: Cannot find script file: main.nf
at nextflow.cli.CmdRun.getScriptFile(CmdRun.groovy:536)
at nextflow.cli.CmdRun.run(CmdRun.groovy:325)
at nextflow.cli.Launcher.run(Launcher.groovy:503)
at nextflow.cli.Launcher.main(Launcher.groovy:658)

12
scripts/README.md Normal file
View File

@@ -0,0 +1,12 @@
# Utility Scripts
This directory contains utility scripts for working with Synthea modules:
- `analyze_patient_data.py` - Analyzes patient data generated by Synthea
- `check_json.py` - Validates JSON structure of module files
- `validate_module.py` - Performs comprehensive validation of modules
- `test_module_exists.py` - Checks if a module exists for a given disease
- `run_module.py` - Script to run a specific module with Synthea
- Other utility scripts for module generation and testing
These scripts complement the core module generator scripts found in the `module_generator/` directory.

View File

@@ -0,0 +1,304 @@
#!/usr/bin/env python3
import os
import sys
import json
import glob
import pandas as pd
from collections import Counter
from datetime import datetime
def analyze_patient_data(input_dir, output_dir, report_format='html', disease_name=None):
"""
Analyze Synthea-generated patient data and create reports.
Args:
input_dir: Directory containing patient JSON files
output_dir: Directory to save analysis outputs
report_format: Format for the report (html or csv)
disease_name: Optional name of the disease being simulated
"""
# Ensure output directory exists
os.makedirs(output_dir, exist_ok=True)
# Find all patient JSON files
patients_files = glob.glob(f"{input_dir}/**/*.json", recursive=True)
print(f"Found {len(patients_files)} patient records for analysis")
if len(patients_files) == 0:
print("No patient files found to analyze.")
with open(os.path.join(output_dir, 'patient_stats.json'), 'w') as f:
json.dump({"error": "No patient files found to analyze"}, f)
return
# Initialize data collectors
patient_data = []
condition_counts = Counter()
medication_counts = Counter()
demographics = {'gender': Counter(), 'age': [], 'race': Counter(), 'ethnicity': Counter()}
# Process each patient file
for patient_file in patients_files:
try:
with open(patient_file, 'r') as f:
data = json.load(f)
# Basic patient info
if 'gender' in data:
demographics['gender'][data['gender']] += 1
if 'birthDate' in data:
# Calculate age based on birth year
birth_year = int(data['birthDate'][:4])
current_year = datetime.now().year
age = current_year - birth_year
demographics['age'].append(age)
# Process race and ethnicity extensions
if 'extension' in data:
for ext in data['extension']:
if 'url' in ext and 'extension' in ext:
if ext['url'].endswith('us-core-race'):
for race_ext in ext['extension']:
if 'valueCoding' in race_ext:
race = race_ext['valueCoding'].get('display', 'Unknown')
demographics['race'][race] += 1
elif ext['url'].endswith('us-core-ethnicity'):
for eth_ext in ext['extension']:
if 'valueCoding' in eth_ext:
ethnicity = eth_ext['valueCoding'].get('display', 'Unknown')
demographics['ethnicity'][ethnicity] += 1
# Collect conditions and medications
if 'entry' in data:
for entry in data['entry']:
if 'resource' in entry:
resource = entry['resource']
# Check for conditions
if resource.get('resourceType') == 'Condition':
if 'code' in resource and 'coding' in resource['code']:
for code in resource['code']['coding']:
if 'display' in code:
condition_counts[code['display']] += 1
# Check for medications
if resource.get('resourceType') == 'MedicationRequest':
if 'medicationCodeableConcept' in resource and 'coding' in resource['medicationCodeableConcept']:
for code in resource['medicationCodeableConcept']['coding']:
if 'display' in code:
medication_counts[code['display']] += 1
except Exception as e:
print(f"Error processing {patient_file}: {e}")
# Prepare statistics
stats = {
'total_patients': len(patients_files),
'disease_name': disease_name,
'demographics': {
'gender_distribution': {gender: count for gender, count in demographics['gender'].items()},
'age_distribution': {
'min': min(demographics['age']) if demographics['age'] else None,
'max': max(demographics['age']) if demographics['age'] else None,
'average': sum(demographics['age']) / len(demographics['age']) if demographics['age'] else None,
'distribution': {'0-18': 0, '19-44': 0, '45-64': 0, '65+': 0}
},
'race_distribution': {race: count for race, count in demographics['race'].items()},
'ethnicity_distribution': {ethnicity: count for ethnicity, count in demographics['ethnicity'].items()}
},
'disease_stats': {
'top_conditions': dict(condition_counts.most_common(15)),
'top_medications': dict(medication_counts.most_common(15))
}
}
# Calculate age distribution
for age in demographics['age']:
if age <= 18:
stats['demographics']['age_distribution']['distribution']['0-18'] += 1
elif age <= 44:
stats['demographics']['age_distribution']['distribution']['19-44'] += 1
elif age <= 64:
stats['demographics']['age_distribution']['distribution']['45-64'] += 1
else:
stats['demographics']['age_distribution']['distribution']['65+'] += 1
# Save statistics to file
with open(os.path.join(output_dir, 'patient_stats.json'), 'w') as f:
json.dump(stats, f, indent=2)
# Generate report in requested format
if report_format == 'html':
generate_html_report(stats, output_dir)
elif report_format == 'csv':
generate_csv_reports(stats, output_dir)
else:
print(f"Unsupported report format: {report_format}. Only stats JSON file created.")
print(f"Analysis complete. Reports generated in {os.path.abspath(output_dir)}")
def generate_html_report(stats, output_dir):
"""Generate an HTML report from the patient statistics."""
disease_title = f" - {stats['disease_name']}" if stats['disease_name'] else ""
html = f'''<!DOCTYPE html>
<html>
<head>
<title>Synthea Patient Analysis{disease_title}</title>
<style>
body {{ font-family: Arial, sans-serif; margin: 20px; }}
h1, h2, h3 {{ color: #333; }}
.container {{ max-width: 1000px; margin: 0 auto; }}
table {{ border-collapse: collapse; width: 100%; margin-bottom: 20px; }}
th, td {{ text-align: left; padding: 8px; border-bottom: 1px solid #ddd; }}
th {{ background-color: #f2f2f2; }}
tr:hover {{background-color: #f5f5f5;}}
.chart {{ margin: 20px 0; height: 300px; }}
</style>
</head>
<body>
<div class="container">
<h1>Synthea Patient Analysis{disease_title}</h1>
<p>Total patients: {stats['total_patients']}</p>
<h2>Demographics</h2>
<h3>Gender Distribution</h3>
<table>
<tr><th>Gender</th><th>Count</th><th>Percentage</th></tr>
'''
for gender, count in stats['demographics']['gender_distribution'].items():
percentage = (count / stats['total_patients']) * 100 if stats['total_patients'] > 0 else 0
html += f"<tr><td>{gender}</td><td>{count}</td><td>{percentage:.1f}%</td></tr>\n"
html += '''
</table>
<h3>Age Distribution</h3>
<table>
<tr><th>Age Group</th><th>Count</th><th>Percentage</th></tr>
'''
for age_group, count in stats['demographics']['age_distribution']['distribution'].items():
percentage = (count / stats['total_patients']) * 100 if stats['total_patients'] > 0 else 0
html += f"<tr><td>{age_group}</td><td>{count}</td><td>{percentage:.1f}%</td></tr>\n"
html += f'''
</table>
<p>Min Age: {stats['demographics']['age_distribution']['min']}</p>
<p>Max Age: {stats['demographics']['age_distribution']['max']}</p>
<p>Average Age: {stats['demographics']['age_distribution']['average']:.1f}</p>
<h3>Race Distribution</h3>
<table>
<tr><th>Race</th><th>Count</th><th>Percentage</th></tr>
'''
for race, count in stats['demographics']['race_distribution'].items():
percentage = (count / stats['total_patients']) * 100 if stats['total_patients'] > 0 else 0
html += f"<tr><td>{race}</td><td>{count}</td><td>{percentage:.1f}%</td></tr>\n"
html += '''
</table>
<h3>Ethnicity Distribution</h3>
<table>
<tr><th>Ethnicity</th><th>Count</th><th>Percentage</th></tr>
'''
for ethnicity, count in stats['demographics']['ethnicity_distribution'].items():
percentage = (count / stats['total_patients']) * 100 if stats['total_patients'] > 0 else 0
html += f"<tr><td>{ethnicity}</td><td>{count}</td><td>{percentage:.1f}%</td></tr>\n"
html += '''
</table>
<h2>Disease Statistics</h2>
<h3>Top Conditions</h3>
<table>
<tr><th>Condition</th><th>Count</th><th>Percentage</th></tr>
'''
for condition, count in stats['disease_stats']['top_conditions'].items():
percentage = (count / stats['total_patients']) * 100 if stats['total_patients'] > 0 else 0
html += f"<tr><td>{condition}</td><td>{count}</td><td>{percentage:.1f}%</td></tr>\n"
html += '''
</table>
<h3>Top Medications</h3>
<table>
<tr><th>Medication</th><th>Count</th><th>Percentage of Patients</th></tr>
'''
for medication, count in stats['disease_stats']['top_medications'].items():
percentage = (count / stats['total_patients']) * 100 if stats['total_patients'] > 0 else 0
html += f"<tr><td>{medication}</td><td>{count}</td><td>{percentage:.1f}%</td></tr>\n"
html += '''
</table>
</div>
</body>
</html>'''
with open(os.path.join(output_dir, 'patient_analysis.html'), 'w') as f:
f.write(html)
def generate_csv_reports(stats, output_dir):
"""Generate CSV reports from the patient statistics."""
import csv
# Demographics CSV
with open(os.path.join(output_dir, 'demographics.csv'), 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow(['Category', 'Type', 'Count', 'Percentage'])
# Gender
for gender, count in stats['demographics']['gender_distribution'].items():
percentage = (count / stats['total_patients']) * 100 if stats['total_patients'] > 0 else 0
writer.writerow(['Gender', gender, count, f"{percentage:.1f}%"])
# Age
for age_group, count in stats['demographics']['age_distribution']['distribution'].items():
percentage = (count / stats['total_patients']) * 100 if stats['total_patients'] > 0 else 0
writer.writerow(['Age', age_group, count, f"{percentage:.1f}%"])
# Race
for race, count in stats['demographics']['race_distribution'].items():
percentage = (count / stats['total_patients']) * 100 if stats['total_patients'] > 0 else 0
writer.writerow(['Race', race, count, f"{percentage:.1f}%"])
# Ethnicity
for ethnicity, count in stats['demographics']['ethnicity_distribution'].items():
percentage = (count / stats['total_patients']) * 100 if stats['total_patients'] > 0 else 0
writer.writerow(['Ethnicity', ethnicity, count, f"{percentage:.1f}%"])
# Conditions CSV
with open(os.path.join(output_dir, 'conditions.csv'), 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow(['Condition', 'Count', 'Percentage'])
for condition, count in stats['disease_stats']['top_conditions'].items():
percentage = (count / stats['total_patients']) * 100 if stats['total_patients'] > 0 else 0
writer.writerow([condition, count, f"{percentage:.1f}%"])
# Medications CSV
with open(os.path.join(output_dir, 'medications.csv'), 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow(['Medication', 'Count', 'Percentage'])
for medication, count in stats['disease_stats']['top_medications'].items():
percentage = (count / stats['total_patients']) * 100 if stats['total_patients'] > 0 else 0
writer.writerow([medication, count, f"{percentage:.1f}%"])
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description="Analyze Synthea patient data and generate reports")
parser.add_argument("--input_dir", required=True, help="Directory containing patient JSON files")
parser.add_argument("--output_dir", default="analysis_output", help="Directory to save analysis outputs")
parser.add_argument("--report_format", default="html", choices=["html", "csv"], help="Format for the reports")
parser.add_argument("--disease_name", help="Name of the disease being simulated")
args = parser.parse_args()
analyze_patient_data(args.input_dir, args.output_dir, args.report_format, args.disease_name)

View File

@@ -0,0 +1,223 @@
#!/usr/bin/env python3
"""
Synthea Module Condition Structure Validator
This script scans all existing Synthea disease modules to check if any violate
the expected condition structure format, particularly looking for nested condition_type
objects that can cause errors during simulation.
Usage:
python check_condition_structure.py [--modules_dir DIRECTORY] [--verbose]
Arguments:
--modules_dir DIRECTORY Path to the modules directory (default: src/main/resources/modules)
--verbose Enable verbose output with detailed issue descriptions
--fix Attempt to automatically fix simple structure issues (experimental)
Example:
python check_condition_structure.py --modules_dir ../modules --verbose
"""
import os
import sys
import json
import glob
import argparse
import logging
from typing import Dict, List, Any, Tuple
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.StreamHandler(sys.stdout)
]
)
logger = logging.getLogger(__name__)
def validate_condition_format(module_json):
"""Validate that conditions in the module follow Synthea's expected format"""
try:
module_dict = json.loads(module_json) if isinstance(module_json, str) else module_json
# Function to recursively check objects for improper condition structure
def check_conditions(obj, path=[]):
issues = []
if isinstance(obj, dict):
# Check if this is a condition object with nested condition_type
if "condition" in obj and isinstance(obj["condition"], dict):
condition = obj["condition"]
current_path = path + ["condition"]
# Look for the improper nested structure
if "condition_type" in condition and isinstance(condition["condition_type"], dict):
issue_path = '.'.join(current_path + ["condition_type"])
issues.append(f"Found nested condition_type in a condition object at path: {issue_path}")
# Recursively check all dictionary values
for key, value in obj.items():
child_issues = check_conditions(value, path + [key])
issues.extend(child_issues)
elif isinstance(obj, list):
# Recursively check all list items
for i, item in enumerate(obj):
child_issues = check_conditions(item, path + [f"[{i}]"])
issues.extend(child_issues)
return issues
# Check the entire module
issues = check_conditions(module_dict)
return len(issues) == 0, issues
except Exception as e:
return False, [f"Validation error: {str(e)}"]
def fix_condition_structure(module_json):
"""Attempt to fix common condition structure issues"""
try:
# Parse the module if it's a string
module_dict = json.loads(module_json) if isinstance(module_json, str) else module_json
fixed = False
def fix_conditions(obj):
nonlocal fixed
if isinstance(obj, dict):
# Check if this is a condition object with nested condition_type
if "condition" in obj and isinstance(obj["condition"], dict):
condition = obj["condition"]
# Fix the improper nested structure:
if "condition_type" in condition and isinstance(condition["condition_type"], dict):
# Replace nested dict with its first key as a string
first_key = list(condition["condition_type"].keys())[0]
condition["condition_type"] = first_key
fixed = True
# Recursively fix all dictionary values
for key, value in list(obj.items()):
if isinstance(value, (dict, list)):
fix_conditions(value)
elif isinstance(obj, list):
# Recursively fix all list items
for item in obj:
if isinstance(item, (dict, list)):
fix_conditions(item)
# Fix the entire module
fix_conditions(module_dict)
# Return the fixed module and whether changes were made
return module_dict, fixed
except Exception as e:
logger.error(f"Error fixing module structure: {e}")
return module_json, False
def main():
parser = argparse.ArgumentParser(description='Validate condition structure in Synthea modules')
parser.add_argument('--modules_dir', type=str, default='src/main/resources/modules',
help='Path to the modules directory')
parser.add_argument('--verbose', action='store_true',
help='Enable verbose output with detailed issue descriptions')
parser.add_argument('--fix', action='store_true',
help='Attempt to automatically fix simple structure issues (experimental)')
args = parser.parse_args()
# Check if modules directory exists
if not os.path.exists(args.modules_dir):
logger.error(f"Modules directory not found: {args.modules_dir}")
sys.exit(1)
# Get all module files
module_files = glob.glob(os.path.join(args.modules_dir, "*.json"))
logger.info(f"Found {len(module_files)} module files to check")
# Track statistics
valid_modules = 0
invalid_modules = 0
fixed_modules = 0
# Check each module
for module_path in module_files:
module_name = os.path.basename(module_path)
try:
# Load module content
with open(module_path, 'r') as f:
module_content = f.read()
# Validate condition structure
try:
module_json = json.loads(module_content)
valid, issues = validate_condition_format(module_json)
if valid:
valid_modules += 1
if args.verbose:
logger.info(f"{module_name}: Valid condition structure")
else:
invalid_modules += 1
if args.fix:
# Attempt to fix the module
fixed_module, was_fixed = fix_condition_structure(module_json)
if was_fixed:
# Write the fixed module back
with open(module_path, 'w') as f:
json.dump(fixed_module, f, indent=2)
# Validate again to confirm
valid_after_fix, remaining_issues = validate_condition_format(fixed_module)
if valid_after_fix:
fixed_modules += 1
logger.info(f"🔧 {module_name}: Fixed condition structure issues")
else:
logger.warning(f"⚠️ {module_name}: Could not fix all condition structure issues")
if args.verbose:
for issue in remaining_issues:
logger.warning(f" - {issue}")
else:
logger.warning(f"⚠️ {module_name}: Could not fix condition structure issues")
if args.verbose:
for issue in issues:
logger.warning(f" - {issue}")
else:
logger.warning(f"⚠️ {module_name}: Invalid condition structure")
if args.verbose:
for issue in issues:
logger.warning(f" - {issue}")
except json.JSONDecodeError as e:
invalid_modules += 1
logger.error(f"{module_name}: Invalid JSON format - {str(e)}")
except Exception as e:
invalid_modules += 1
logger.error(f"{module_name}: Error processing file - {str(e)}")
# Print summary
logger.info("\nSummary:")
logger.info(f"Total modules checked: {len(module_files)}")
logger.info(f"Valid modules: {valid_modules}")
logger.info(f"Invalid modules: {invalid_modules}")
if args.fix:
logger.info(f"Modules fixed: {fixed_modules}")
if invalid_modules > 0:
logger.warning("Some modules have condition structure issues that may cause problems in Synthea")
if not args.fix:
logger.info("Run with --fix to attempt automatic fixes for the issues")
else:
logger.info("All modules have valid condition structure")
if __name__ == "__main__":
main()

14
scripts/check_json.py Normal file
View File

@@ -0,0 +1,14 @@
import json
import sys
path = sys.argv[1]
with open(path, 'r') as f:
content = f.read()
print(f"File has {content.count('{')} opening braces and {content.count('}')} closing braces")
try:
json.loads(content)
print('Valid JSON')
except Exception as e:
print(f'Invalid JSON: {e}')

262
scripts/cleanup.sh Executable file
View File

@@ -0,0 +1,262 @@
#!/bin/bash
# Synthea-All-Diseases Repository Cleanup Script
# This script removes unnecessary files and keeps only the essential ones for the Synthea module generator
echo "Starting repository cleanup..."
# Create backup directory
mkdir -p backup
mkdir -p backup/scripts # Create a directory for Python scripts
mkdir -p backup/modules # Create a directory for modules
mkdir -p backup/module_generator # Create a directory for module generator scripts
# 1. Keep essential Nextflow files, remove others
echo "Handling Nextflow files..."
cp main.nf backup/
rm -f build_synthea.nf synthea_module_generator_old.nf minimal_test.nf fresh_synthea.nf simple_synthea.nf test_workflow.nf new_synthea.nf minimal_working.nf
# Keep synthea_module_generator.nf around for reference but not used
mv synthea_module_generator.nf backup/
# 2. Keep essential Python scripts, Docker files, and configuration files
echo "Keeping essential files..."
if [ -d "src/main/python" ]; then
cp -r src/main/python backup/module_generator/
fi
if [ -d "src/main/resources/modules" ]; then
cp -r src/main/resources/modules/* backup/modules/
fi
cp Dockerfile docker-compose.yml CLAUDE.md .env.example nextflow.config README.md backup/
cp DOCKER_README.md SYNTHEA_GUIDE.md backup/ 2>/dev/null || : # Keep additional README files
# Backup .env file if it exists
if [ -f ".env" ]; then
cp .env backup/
fi
# 3. Back up all Python scripts in the root directory
echo "Backing up Python scripts..."
# Key scripts - these will be kept in the scripts directory after cleanup
# The only key script we'll keep in the root is check_condition_structure.py for convenience
key_scripts=("check_condition_structure.py")
for script in "${key_scripts[@]}"; do
if [ -f "$script" ]; then
cp "$script" backup/
echo " Backed up key script for root: $script"
fi
done
# All other Python scripts - these will be moved to scripts/ directory
for script in *.py; do
if [ -f "$script" ] && [[ ! " ${key_scripts[@]} " =~ " ${script} " ]]; then
cp "$script" backup/scripts/
echo " Backed up utility script: $script"
fi
done
# 4. Remove ALL Synthea code - we'll clone it in Docker
echo "Removing ALL Synthea source code..."
echo "This will be cloned during Docker build based on Dockerfile..."
# Remove the entire src directory - we'll recreate what we need
rm -rf src/
# Remove any Synthea build files/directories
rm -rf build/ output/ simulator/ lib/ logs/
# Remove any Synthea run files
rm -f run_synthea run_synthea.bat synthea *.jar
# 5. Remove other experimental or temporary files
echo "Removing experimental and temporary files..."
rm -f *.log *.txt trace.txt
rm -f error_output.txt generate_module.sh run_synthetic_data_generation.sh
rm -f build_docker.sh entrypoint.sh run_module_generator.sh generate_samples.sh test_run.sh
rm -f run_flexporter .DS_Store
# 6. Remove gradle files and other unnecessary files
echo "Removing additional unnecessary files..."
rm -f build.gradle gradlew gradlew.bat settings.gradle
rm -rf gradle/ .gradle/
# Note: Keeping .git, .gitignore, .github for version control
rm -rf .nextflow/ .nextflow.log* nextflow-*.zip
# Keep LICENSE files but remove other documentation that will be included from Synthea
rm -f CODE_OF_CONDUCT.md NOTICE
rm -f *.bak *~
# 7. Create clean directory structure for the repository
echo "Creating clean directory structure..."
mkdir -p modules # Top-level modules directory
mkdir -p module_generator # Module generator directory (renamed from python)
mkdir -p scripts # Utility scripts directory
# 8. Restore files to the cleaned structure
echo "Restoring files to cleaned structure..."
# Restore modules
if [ -d "backup/modules" ]; then
cp -r backup/modules/* modules/ 2>/dev/null || :
echo " Restored modules to modules/ directory"
fi
# Restore Module generator core scripts
if [ -d "backup/module_generator" ]; then
cp -r backup/module_generator/* module_generator/ 2>/dev/null || :
echo " Restored core generator scripts to module_generator/ directory"
fi
# Restore key Python scripts to root directory
for script in "${key_scripts[@]}"; do
if [ -f "backup/$script" ]; then
cp "backup/$script" ./
echo " Restored key script to root: $script"
fi
done
# Restore utility Python scripts to scripts/ directory
if [ -d "backup/scripts" ]; then
cp backup/scripts/* scripts/ 2>/dev/null || :
echo " Restored utility scripts to scripts/ directory"
fi
# Restore root files
cp backup/main.nf backup/Dockerfile backup/docker-compose.yml backup/CLAUDE.md backup/nextflow.config backup/.env.example backup/README.md ./ 2>/dev/null || :
if [ -f "backup/DOCKER_README.md" ]; then
cp backup/DOCKER_README.md ./
fi
if [ -f "backup/SYNTHEA_GUIDE.md" ]; then
cp backup/SYNTHEA_GUIDE.md ./
fi
# Restore .env if it existed
if [ -f "backup/.env" ]; then
cp backup/.env ./
echo " Restored .env file"
fi
# 9. Update the Dockerfile to reference the new directory structure
echo "Updating Dockerfile references if needed..."
if [ -f "Dockerfile" ]; then
# Update the Dockerfile to use the new directory structure
sed -i.bak 's|COPY src/main/python/|COPY module_generator/|g' Dockerfile
sed -i.bak 's|COPY python/|COPY module_generator/|g' Dockerfile
sed -i.bak 's|COPY src/main/resources/modules/|COPY modules/|g' Dockerfile
sed -i.bak 's|src/main/python/|module_generator/|g' Dockerfile
sed -i.bak 's|src/main/resources/modules|modules|g' Dockerfile
# Update script paths if needed
sed -i.bak 's|/app/src/main/python/|/app/module_generator/|g' Dockerfile
rm -f Dockerfile.bak
fi
# 10. Update the main.nf file to reference the new directory structure
echo "Updating main.nf references if needed..."
if [ -f "main.nf" ]; then
# Update the main.nf file to use the new directory structure
sed -i.bak 's|src/main/resources/modules|modules|g' main.nf
sed -i.bak 's|src/main/python|module_generator|g' main.nf
sed -i.bak 's|python/|module_generator/|g' main.nf
rm -f main.nf.bak
fi
# 11. Create a simple README for the scripts directory
echo "Creating README for scripts directory..."
cat > scripts/README.md << 'EOF'
# Utility Scripts
This directory contains utility scripts for working with Synthea modules:
- `analyze_patient_data.py` - Analyzes patient data generated by Synthea
- `check_json.py` - Validates JSON structure of module files
- `validate_module.py` - Performs comprehensive validation of modules
- `test_module_exists.py` - Checks if a module exists for a given disease
- `run_module.py` - Script to run a specific module with Synthea
- Other utility scripts for module generation and testing
These scripts complement the core module generator scripts found in the `module_generator/` directory.
EOF
# Update README.md with instructions on using the cleaned repo
echo "Updating README..."
cat > README.md << 'EOF'
# Synthea All Diseases
This repository contains a workflow for generating Synthea disease modules using Claude AI and generating synthetic patient data.
## Repository Structure
- `module_generator/` - Core module generation scripts
- `modules/` - Generated disease modules
- `scripts/` - Utility Python scripts and tools
- `main.nf` - Nextflow workflow for module generation and patient data generation
- `Dockerfile` and `docker-compose.yml` - Docker configuration
## Key Files
- `check_condition_structure.py` - Validates condition structure in modules
- `main.nf` - Main workflow file for generating modules and patient data
## Running the Pipeline
### Prerequisites
- Docker and Docker Compose
- Nextflow
- Anthropic API key (for Claude AI)
### Setup
1. Clone this repository
2. Copy `.env.example` to `.env` and add your Anthropic API key
3. Run with Docker Compose:
```
docker-compose up
```
### Running the Workflow
```
nextflow run main.nf --disease_name "Disease Name" [OPTIONS]
```
For a full list of options, run:
```
nextflow run main.nf --help
```
## Key Features
- Generate modules for diseases that don't exist in Synthea
- Validate condition structure in generated modules
- Generate synthetic patient data using the modules
- Analyze generated patient data
## Documentation
- See `CLAUDE.md` for additional development guidelines
- See `DOCKER_README.md` for Docker setup and usage
- See `SYNTHEA_GUIDE.md` for detailed usage examples and scenarios
- See `scripts/README.md` for information about utility scripts
## License
This project uses the same license as Synthea.
EOF
# 12. Update docker-compose.yml to reference the new directory structure
echo "Updating docker-compose.yml references if needed..."
if [ -f "docker-compose.yml" ]; then
# No changes needed as it uses relative paths and volume mounts
echo " No changes needed for docker-compose.yml"
fi
echo "Cleanup complete! All essential files have been kept, and unnecessary files have been removed."
echo "Repository structure has been simplified to:"
echo " - module_generator/ (core module generation scripts)"
echo " - modules/ (disease modules)"
echo " - scripts/ (utility scripts)"
echo " - check_condition_structure.py (in root for easy access)"
echo ""
echo "The following important files were preserved:"
echo " - .git/ (version control repository)"
echo " - .gitignore (version control configuration)"
echo " - .env (environment configuration if it existed)"
echo " - .github/ (GitHub configuration if it existed)"
echo ""
echo "Optional: Remove the backup directory after verifying everything works: rm -rf backup"

175
scripts/generate_batch.py Executable file
View File

@@ -0,0 +1,175 @@
#!/usr/bin/env python3
import os
import sys
import csv
import time
import argparse
import subprocess
import concurrent.futures
import re
# Global variables
ARGS = None
def normalize_disease_name(name):
"""Convert a disease name to a normalized filename"""
# Convert to lowercase
name = name.lower()
# Replace special characters with underscores
name = re.sub(r'[^a-z0-9]+', '_', name)
# Remove leading/trailing underscores
name = name.strip('_')
# Ensure the name is not empty
if not name:
name = "unknown_disease"
return name
def process_disease(disease_entry):
"""Process a single disease from the CSV"""
disease_name = disease_entry.get("disease_name", "")
normalized_name = normalize_disease_name(disease_name)
icd10 = disease_entry.get("id", "")
category = disease_entry.get("disease_category", "")
print(f"\n{'='*80}")
print(f"Processing disease: {disease_name}")
print(f"ICD-10 code: {icd10}")
print(f"Category: {category}")
# Skip if module already exists (unless --force flag is used)
module_path = f"src/main/resources/modules/{normalized_name}.json"
if os.path.exists(module_path) and not ARGS.force:
print(f"✅ Module already exists at {module_path}, skipping")
return {"name": disease_name, "status": "skipped", "path": module_path}
# Create the command
cmd = ["python3", "generate_module.py", "--disease", disease_name, "--no-interactive"]
if icd10:
cmd.extend(["--icd10", icd10])
if category:
cmd.extend(["--category", category])
# Add auto-fallback option if requested
if ARGS.auto_fallback:
cmd.append("--auto-fallback")
# Run the generator
try:
print(f"Executing: {' '.join(cmd)}")
process = subprocess.run(cmd, check=True, text=True, capture_output=True)
print(f"✅ Successfully generated module for {disease_name}")
print(process.stdout.strip())
return {"name": disease_name, "status": "success", "path": module_path}
except subprocess.CalledProcessError as e:
print(f"❌ Failed to generate module for {disease_name}")
print(f"Error: {str(e)}")
print(f"STDOUT: {e.stdout}")
print(f"STDERR: {e.stderr}")
return {"name": disease_name, "status": "error", "error": str(e), "path": None}
def main():
"""Main function to process diseases from the CSV"""
global ARGS
parser = argparse.ArgumentParser(description='Generate Synthea modules for diseases')
parser.add_argument('--category', help='Only process diseases in this category')
parser.add_argument('--disease', help='Only process a specific disease (by name)')
parser.add_argument('--limit', type=int, help='Limit number of diseases to process')
parser.add_argument('--parallel', type=int, default=1, help='Number of parallel processes')
parser.add_argument('--skip-existing', action='store_true', help='Skip diseases that already have modules')
parser.add_argument('--csv-path', default='src/main/resources/disease_list.csv', help='Path to disease list CSV')
parser.add_argument('--force', action='store_true', help='Force generation even if module already exists')
parser.add_argument('--auto-fallback', action='store_true', help='Enable auto-fallback option')
args = parser.parse_args()
ARGS = args
# Read the disease list CSV
if not os.path.exists(args.csv_path):
print(f"Error: Disease list CSV not found at {args.csv_path}")
sys.exit(1)
print(f"Reading disease list from {args.csv_path}")
try:
with open(args.csv_path, 'r') as f:
reader = csv.DictReader(f)
diseases = list(reader)
except Exception as e:
print(f"Error reading CSV: {str(e)}")
sys.exit(1)
print(f"Found {len(diseases)} diseases in the CSV")
# Filter diseases
if args.category:
diseases = [d for d in diseases if (d.get('disease_category', '').lower() == args.category.lower())]
print(f"Filtered to {len(diseases)} diseases in category '{args.category}'")
if args.disease:
# Try to find an exact match first
disease_name_lower = args.disease.lower()
exact_match = [d for d in diseases if d.get("disease_name", "").lower() == disease_name_lower]
if exact_match:
diseases = exact_match
else:
# Try to find a disease that contains the specified name
partial_matches = [d for d in diseases if disease_name_lower in d.get("disease_name", "").lower()]
if partial_matches:
diseases = partial_matches
print(f"Found {len(diseases)} partial matches for '{args.disease}'")
else:
print(f"No matches found for disease '{args.disease}'")
sys.exit(1)
if args.limit and args.limit > 0:
diseases = diseases[:args.limit]
print(f"Limited to {args.limit} diseases")
# Process the diseases
total = len(diseases)
print(f"\nProcessing {total} diseases with {args.parallel} parallel workers")
start_time = time.time()
if args.parallel > 1:
with concurrent.futures.ProcessPoolExecutor(max_workers=args.parallel) as executor:
results = list(executor.map(process_disease, diseases))
else:
results = [process_disease(disease) for disease in diseases]
end_time = time.time()
elapsed = end_time - start_time
# Summarize results
success_count = sum(1 for r in results if r["status"] == "success")
skipped_count = sum(1 for r in results if r["status"] == "skipped")
error_count = sum(1 for r in results if r["status"] == "error")
print("\n" + "="*80)
print(f"SUMMARY: Processed {total} diseases in {elapsed:.2f} seconds")
print(f"- Successfully generated: {success_count}")
print(f"- Skipped (already exist): {skipped_count}")
print(f"- Failed: {error_count}")
# List errors if any
if error_count > 0:
print("\nFAILED DISEASES:")
for result in results:
if result["status"] == "error":
print(f"- {result['name']}: {result.get('error', 'Unknown error')}")
# Exit with error code if any failures
sys.exit(1)
print("\nAll done! 🎉")
if __name__ == "__main__":
main()

468
scripts/generate_module.py Executable file
View File

@@ -0,0 +1,468 @@
#!/usr/bin/env python3
import os
import sys
import json
import re
import anthropic
import csv
import argparse
# Define global variables
DISEASE_NAME = ""
OUTPUT_FILE = ""
icd10_code = ""
disease_category = ""
use_interactive = True
use_auto_fallback = False
def normalize_disease_name(name):
# Normalize disease name for filename
normalized_name = name.lower().replace(' ', '_').replace('-', '_')
normalized_name = ''.join(c if c.isalnum() or c == '_' else '_' for c in normalized_name)
normalized_name = '_'.join(filter(None, normalized_name.split('_')))
return normalized_name
def generate_module():
# Initialize the Anthropic client
api_key = os.environ.get('ANTHROPIC_API_KEY')
if not api_key:
print("Error: ANTHROPIC_API_KEY environment variable is not set")
sys.exit(1)
client = anthropic.Anthropic(api_key=api_key)
# Step 1: Ask Claude for clinical details in a structured format, not JSON
print("Step 1: Getting clinical details from Claude...")
# Prepare disease information for the prompt
disease_info = f"Disease name: {DISEASE_NAME}"
if icd10_code:
disease_info += f"\nICD-10 code: {icd10_code}"
if disease_category:
disease_info += f"\nCategory: {disease_category}"
# Construct a prompt that asks for structured data, not JSON
prompt = f"""I need information to create a Synthea disease module for {DISEASE_NAME}.
{disease_info}
Please provide the following information in a structured format (NOT JSON):
1. DESCRIPTION: A brief description of the disease (3-5 sentences)
2. RISK_FACTORS: Age ranges, gender factors, and/or other risk factors for this disease
3. SYMPTOMS: List the main symptoms of the disease
4. DIAGNOSTIC_TESTS: Tests typically used to diagnose this condition
5. TREATMENTS: List treatments for this disease, including:
- Medications (with their class and purpose)
- Procedures
- Other interventions
6. COMPLICATIONS: Possible complications of this disease
7. PROGRESSION: Typical progression of the disease, including:
- How it starts
- How it typically develops
- Possible outcomes
8. FOLLOW_UP: Typical follow-up care needed
For medications, just provide generic names - I'll handle the RxNorm codes.
For conditions and procedures, just provide plain English names - I'll handle the coding.
Please provide this information in a straightforward, structured text format. Do NOT use JSON.
"""
# Get clinical details
try:
response = client.messages.create(
model="claude-3-7-sonnet-20250219",
max_tokens=4000,
temperature=0.2,
messages=[
{"role": "user", "content": prompt}
]
)
# Extract the response text
clinical_details = response.content[0].text
# Save the raw clinical details for reference
os.makedirs(os.path.dirname(OUTPUT_FILE), exist_ok=True)
with open(f"{OUTPUT_FILE}.details", "w") as f:
f.write(clinical_details)
print(f"Clinical details saved to {OUTPUT_FILE}.details")
# Step 2: Now build a valid module with the clinical details
print("Step 2: Building module with clinical details...")
# Extract information from the structured response
description_match = re.search(r'##\s*1\.\s*DESCRIPTION(.*?)(?=##\s*2\.)', clinical_details, re.DOTALL)
risk_factors_match = re.search(r'##\s*2\.\s*RISK_FACTORS(.*?)(?=##\s*3\.)', clinical_details, re.DOTALL)
symptoms_match = re.search(r'##\s*3\.\s*SYMPTOMS(.*?)(?=##\s*4\.)', clinical_details, re.DOTALL)
diagnostic_tests_match = re.search(r'##\s*4\.\s*DIAGNOSTIC_TESTS(.*?)(?=##\s*5\.)', clinical_details, re.DOTALL)
treatments_match = re.search(r'##\s*5\.\s*TREATMENTS(.*?)(?=##\s*6\.)', clinical_details, re.DOTALL)
complications_match = re.search(r'##\s*6\.\s*COMPLICATIONS(.*?)(?=##\s*7\.)', clinical_details, re.DOTALL)
progression_match = re.search(r'##\s*7\.\s*PROGRESSION(.*?)(?=##\s*8\.)', clinical_details, re.DOTALL)
follow_up_match = re.search(r'##\s*8\.\s*FOLLOW_UP(.*?)(?=$)', clinical_details, re.DOTALL)
# Extract text from matches
description = description_match.group(1).strip() if description_match else f"A module for {DISEASE_NAME}"
risk_factors = risk_factors_match.group(1).strip() if risk_factors_match else ""
symptoms = symptoms_match.group(1).strip() if symptoms_match else ""
diagnostic_tests = diagnostic_tests_match.group(1).strip() if diagnostic_tests_match else ""
treatments = treatments_match.group(1).strip() if treatments_match else ""
complications = complications_match.group(1).strip() if complications_match else ""
progression = progression_match.group(1).strip() if progression_match else ""
follow_up = follow_up_match.group(1).strip() if follow_up_match else ""
print(f"Extracted: {len(description)} chars description, {len(symptoms)} chars symptoms, {len(treatments)} chars treatments")
# Extract symptoms as a list
symptom_list = []
if symptoms_match:
# For structured format with bullet points
symptom_lines = re.findall(r'[-*]\s*(.*?)(?:\n|$)', symptoms, re.MULTILINE)
if symptom_lines:
symptom_list = [s.strip() for s in symptom_lines if s.strip()]
else:
# Try to split by newlines for a less structured format
symptom_list = [s.strip() for s in symptoms.split('\n') if s.strip()]
# If that doesn't give us anything, just add the whole text as one symptom
if not symptom_list and symptoms.strip():
symptom_list = [symptoms.strip()]
print(f"Found {len(symptom_list)} symptoms")
# Extract medications from treatments
medications = []
if treatments_match:
# Find the "Medications:" section
meds_section_match = re.search(r'Medications?:\s*(.*?)(?=(?:- Procedures:|$))', treatments, re.DOTALL)
if meds_section_match:
meds_section = meds_section_match.group(1).strip()
# Extract main medication names from list items with explanations
# Format is typically: "- Medication name (explanation)" or "- Medication name - explanation"
med_items = re.findall(r'[-*]\s*(.*?)(?=[-*]|\n\n|\n- |$)', meds_section, re.DOTALL)
for item in med_items:
item = item.strip()
if not item:
continue
# Extract just the medication name, not the explanation
med_match = re.match(r'([^(]+)(?:\(|-).*', item)
if med_match:
med_name = med_match.group(1).strip()
else:
med_name = item.split('(')[0].strip()
# Clean up common patterns
med_name = re.sub(r'\s*\([^)]*\)', '', med_name) # Remove parentheticals
med_name = re.sub(r'\s*-.*', '', med_name) # Remove after dash
# Skip descriptive phrases that aren't medications
if any(phrase in med_name.lower() for phrase in ['reduce', 'block', 'prevent', 'for']):
continue
# Look for multiple medications in parentheses
if ',' in med_name:
for m in med_name.split(','):
m = m.strip()
if m and not any(m.lower() in existing.lower() for existing in medications):
medications.append(m)
else:
if med_name and not any(med_name.lower() in existing.lower() for existing in medications):
medications.append(med_name)
print(f"Found {len(medications)} medications: {', '.join(medications[:5])}")
# Start with a basic module template
module = {
"name": DISEASE_NAME,
"remarks": [],
"states": {
"Initial": {
"type": "Initial",
"direct_transition": "Age_Guard"
},
"Age_Guard": {
"type": "Guard",
"allow": {
"condition_type": "Age",
"operator": ">=",
"quantity": 18,
"unit": "years"
},
"direct_transition": "Delay_Until_Onset"
},
"Delay_Until_Onset": {
"type": "Delay",
"range": {
"low": 0,
"high": 20,
"unit": "years"
},
"direct_transition": "Onset"
},
"Onset": {
"type": "ConditionOnset",
"target_encounter": "Diagnosis_Encounter",
"codes": [
{
"system": "SNOMED-CT",
"code": "64109004",
"display": DISEASE_NAME
}
],
"direct_transition": "Diagnosis_Encounter"
},
"Diagnosis_Encounter": {
"type": "Encounter",
"encounter_class": "ambulatory",
"reason": "Onset",
"codes": [
{
"system": "SNOMED-CT",
"code": "185347001",
"display": "Encounter for problem"
}
],
"direct_transition": "End_Diagnosis_Encounter"
},
"End_Diagnosis_Encounter": {
"type": "EncounterEnd"
# direct_transition will be set later
}
}
}
# Add description to remarks
if description:
for line in description.split('\n'):
line = line.strip()
if line:
module["remarks"].append(line)
# Add ICD-10 code if available
if icd10_code:
module["remarks"].append(f"ICD-10 code: {icd10_code}")
# Add category if available
if disease_category:
module["remarks"].append(f"Category: {disease_category}")
# Make sure remarks is not empty
if not module["remarks"]:
module["remarks"].append(f"Generated module for {DISEASE_NAME}")
# Add risk factors to remarks if available
if risk_factors:
module["remarks"].append(f"Risk factors: {risk_factors.replace('\n', ' ')}")
# Add symptoms if available
symptom_i = 0
current_state = "End_Diagnosis_Encounter"
if symptom_list:
for i, symptom in enumerate(symptom_list[:3]): # Limit to 3 symptoms
symptom_name = symptom.strip()
if not symptom_name:
continue
state_name = f"Symptom_{symptom_i}"
symptom_i += 1
module["states"][state_name] = {
"type": "ConditionOnset",
"target_encounter": "Diagnosis_Encounter",
"codes": [
{
"system": "SNOMED-CT",
"code": "418107008", # Default symptom code
"display": symptom_name
}
]
}
# Connect states
module["states"][current_state]["direct_transition"] = state_name
current_state = state_name
# Add diagnostic tests if available
if diagnostic_tests:
test_lines = re.findall(r'[-*]\s*(.*?)(?:\n|$)', diagnostic_tests, re.MULTILINE)
tests = [t.strip() for t in test_lines if t.strip()]
if tests:
for i, test in enumerate(tests[:2]): # Limit to 2 tests
test_name = test.strip()
if not test_name:
continue
state_name = f"DiagnosticTest_{i}"
module["states"][state_name] = {
"type": "Procedure",
"target_encounter": "Diagnosis_Encounter",
"reason": "Onset",
"codes": [
{
"system": "SNOMED-CT",
"code": "386053000", # Default diagnostic procedure code
"display": test_name
}
]
}
# Connect states
module["states"][current_state]["direct_transition"] = state_name
current_state = state_name
# Add medications if found
if medications:
for i, med in enumerate(medications[:3]): # Limit to 3 medications to keep module manageable
med_name = med.strip()
if not med_name:
continue
state_name = f"Prescribe_{i}"
module["states"][state_name] = {
"type": "MedicationOrder",
"target_encounter": "Diagnosis_Encounter",
"reason": "Onset",
"codes": [
{
"system": "RxNorm",
"code": "308047", # Default code
"display": med_name
}
]
}
# Connect states
module["states"][current_state]["direct_transition"] = state_name
current_state = state_name
# Connect to Follow-up
module["states"][current_state]["direct_transition"] = "Follow_Up_Encounter"
# Add follow-up encounter
module["states"]["Follow_Up_Encounter"] = {
"type": "Encounter",
"encounter_class": "ambulatory",
"reason": "Onset",
"codes": [
{
"system": "SNOMED-CT",
"code": "390906007",
"display": "Follow-up encounter"
}
],
"direct_transition": "End_Follow_Up_Encounter"
}
module["states"]["End_Follow_Up_Encounter"] = {
"type": "EncounterEnd",
"direct_transition": "Terminal"
}
module["states"]["Terminal"] = {
"type": "Terminal"
}
# Format the JSON for output
formatted_json = json.dumps(module, indent=2)
# Save the module
with open(OUTPUT_FILE, "w") as f:
f.write(formatted_json)
print(f"✅ Successfully generated module and saved to {OUTPUT_FILE}")
return 0
except Exception as e:
print(f"❌ Error: {str(e)}")
# Write the error to a file
with open(f"{OUTPUT_FILE}.error", "w") as f:
f.write(f"Error: {str(e)}")
return 1
def main():
# Parse command line arguments
parser = argparse.ArgumentParser(description='Generate a Synthea module for a disease')
parser.add_argument('--disease', type=str, required=True, help='Disease name')
parser.add_argument('--icd10', type=str, help='ICD-10 code')
parser.add_argument('--category', type=str, help='Disease category')
parser.add_argument('--no-interactive', action='store_true', help='Skip interactive prompts, for batch processing')
parser.add_argument('--auto-fallback', action='store_true', help='Automatically use fallback template if JSON parsing fails')
parser.add_argument('--force', action='store_true', help='Force regeneration even if module already exists')
args = parser.parse_args()
# Set global variables
global DISEASE_NAME, OUTPUT_FILE, use_interactive, use_auto_fallback
DISEASE_NAME = args.disease
normalized_name = normalize_disease_name(DISEASE_NAME)
OUTPUT_FILE = f"src/main/resources/modules/{normalized_name}.json"
use_interactive = not args.no_interactive
use_auto_fallback = args.auto_fallback
# Use provided ICD-10 code or category if specified
global icd10_code, disease_category
icd10_code = args.icd10
disease_category = args.category
print(f"Disease name: {DISEASE_NAME}")
print(f"Normalized filename: {normalized_name}.json")
# Check if module already exists
if os.path.exists(OUTPUT_FILE):
print(f"✅ Module already exists at: {OUTPUT_FILE}")
if args.force:
print("Force flag set. Regenerating module.")
else:
return 0
else:
print(f"❌ Module not found at: {OUTPUT_FILE}")
# If no ICD-10 code provided, look up in disease list CSV
if not icd10_code:
csv_path = "src/main/resources/disease_list.csv"
if os.path.exists(csv_path):
print(f"Looking up disease information in {csv_path}...")
try:
with open(csv_path, 'r') as f:
reader = csv.DictReader(f)
for row in reader:
if row.get("disease_name", "").lower() == DISEASE_NAME.lower():
icd10_code = row.get("id", "")
disease_category = row.get("disease_category", "")
print(f"Found matching disease in CSV:")
print(f"- ICD-10 code: {icd10_code}")
print(f"- Category: {disease_category}")
break
else:
print("No matching disease found in CSV. Continuing without ICD-10 code.")
except Exception as e:
print(f"Error reading CSV: {str(e)}")
print("Continuing without ICD-10 code.")
# Ensure ANTHROPIC_API_KEY is set
if not os.environ.get('ANTHROPIC_API_KEY'):
print("Error: ANTHROPIC_API_KEY environment variable is not set")
return 1
# Ask Claude to generate the module
generate_module()
return 0
if __name__ == "__main__":
sys.exit(main())

321
scripts/patient_analysis.py Executable file
View File

@@ -0,0 +1,321 @@
#!/usr/bin/env python3
import os
import sys
import json
import glob
import argparse
from collections import Counter
from datetime import datetime
def analyze_patient_data(disease_name, input_dir, output_dir, format_type="html"):
print(f"Analyzing patient data for {disease_name}...")
# Create the output directory if it doesn't exist
os.makedirs(output_dir, exist_ok=True)
# Find all patient JSON files
patients_files = glob.glob(f"{input_dir}/*.json")
patients_files = [f for f in patients_files if not 'hospitalInformation' in f and not 'practitionerInformation' in f]
print(f"Found {len(patients_files)} patient records for analysis")
if len(patients_files) == 0:
print("No patient files found to analyze.")
with open(os.path.join(output_dir, f"{disease_name.lower().replace(' ', '_')}_report.html"), 'w') as f:
f.write(f"<html><body><h1>Analysis Report for {disease_name}</h1><p>No patient files found to analyze.</p></body></html>")
# Create empty CSV and JSON files
with open(os.path.join(output_dir, f"{disease_name.lower().replace(' ', '_')}_report.csv"), 'w') as f:
f.write("No patient files found to analyze.\n")
with open(os.path.join(output_dir, f"{disease_name.lower().replace(' ', '_')}_report.json"), 'w') as f:
f.write('{"error": "No patient files found to analyze."}\n')
return
# Initialize data collectors
demographics = {'gender': Counter(), 'age': [], 'race': Counter(), 'ethnicity': Counter()}
condition_counts = Counter()
medication_counts = Counter()
# Process each patient file
for patient_file in patients_files:
try:
with open(patient_file, 'r') as f:
data = json.load(f)
# Skip non-patient resources
if 'resourceType' in data and data['resourceType'] == 'Patient':
# Basic patient info
if 'gender' in data:
demographics['gender'][data['gender']] += 1
if 'birthDate' in data:
# Calculate age based on birth year
birth_year = int(data['birthDate'][:4])
current_year = datetime.now().year
age = current_year - birth_year
demographics['age'].append(age)
# Process race and ethnicity extensions
if 'extension' in data:
for ext in data.get('extension', []):
if 'url' in ext and 'extension' in ext:
if ext['url'].endswith('us-core-race'):
for race_ext in ext['extension']:
if 'valueCoding' in race_ext:
race = race_ext['valueCoding'].get('display', 'Unknown')
demographics['race'][race] += 1
elif ext['url'].endswith('us-core-ethnicity'):
for eth_ext in ext['extension']:
if 'valueCoding' in eth_ext:
ethnicity = eth_ext['valueCoding'].get('display', 'Unknown')
demographics['ethnicity'][ethnicity] += 1
# Check for Bundle resources with entries
if 'resourceType' in data and data['resourceType'] == 'Bundle' and 'entry' in data:
bundle_has_patient = False
for entry in data['entry']:
if 'resource' in entry:
resource = entry['resource']
# Check if this bundle contains a patient
if resource.get('resourceType') == 'Patient':
bundle_has_patient = True
# Basic patient info
if 'gender' in resource:
demographics['gender'][resource['gender']] += 1
if 'birthDate' in resource:
# Calculate age based on birth year
birth_year = int(resource['birthDate'][:4])
current_year = datetime.now().year
age = current_year - birth_year
demographics['age'].append(age)
# Process race and ethnicity extensions
if 'extension' in resource:
for ext in resource.get('extension', []):
if 'url' in ext and 'extension' in ext:
if ext['url'].endswith('us-core-race'):
for race_ext in ext['extension']:
if 'valueCoding' in race_ext:
race = race_ext['valueCoding'].get('display', 'Unknown')
demographics['race'][race] += 1
elif ext['url'].endswith('us-core-ethnicity'):
for eth_ext in ext['extension']:
if 'valueCoding' in eth_ext:
ethnicity = eth_ext['valueCoding'].get('display', 'Unknown')
demographics['ethnicity'][ethnicity] += 1
# Check for conditions
if resource.get('resourceType') == 'Condition':
if 'code' in resource and 'coding' in resource['code']:
for code in resource['code']['coding']:
if 'display' in code:
condition_counts[code['display']] += 1
# Check for medications
if resource.get('resourceType') == 'MedicationRequest':
if 'medicationCodeableConcept' in resource and 'coding' in resource['medicationCodeableConcept']:
for code in resource['medicationCodeableConcept']['coding']:
if 'display' in code:
medication_counts[code['display']] += 1
except Exception as e:
print(f"Error processing {patient_file}: {e}")
# Calculate total patients (count unique patient files)
total_patients = sum(demographics['gender'].values())
if total_patients == 0:
print("Warning: No patient demographics found. Setting total_patients to file count.")
total_patients = len(patients_files)
print(f"Total patients found: {total_patients}")
print(f"Gender distribution: {dict(demographics['gender'])}")
if total_patients == 0:
total_patients = 1 # Avoid division by zero
# Generate HTML report
if format_type.lower() in ["html", "all"]:
create_html_report(disease_name, output_dir, demographics, condition_counts, medication_counts, total_patients)
# Generate CSV report
if format_type.lower() in ["csv", "all"]:
create_csv_report(disease_name, output_dir, demographics, condition_counts, medication_counts, total_patients)
# Generate JSON report
if format_type.lower() in ["json", "all"]:
create_json_report(disease_name, output_dir, demographics, condition_counts, medication_counts, total_patients)
print(f"Analysis complete. Reports generated in {output_dir}")
def create_html_report(disease_name, output_dir, demographics, condition_counts, medication_counts, total_patients):
with open(os.path.join(output_dir, f"{disease_name.lower().replace(' ', '_')}_report.html"), 'w') as f:
f.write(f'''<!DOCTYPE html>
<html>
<head>
<title>Synthea Patient Analysis - {disease_name}</title>
<style>
body {{ font-family: Arial, sans-serif; margin: 20px; }}
h1, h2, h3 {{ color: #333; }}
.container {{ max-width: 1000px; margin: 0 auto; }}
table {{ border-collapse: collapse; width: 100%; margin-bottom: 20px; }}
th, td {{ text-align: left; padding: 8px; border-bottom: 1px solid #ddd; }}
th {{ background-color: #f2f2f2; }}
tr:hover {{background-color: #f5f5f5;}}
</style>
</head>
<body>
<div class="container">
<h1>Synthea Patient Analysis - {disease_name}</h1>
<p>Total patients analyzed: {total_patients}</p>
<h2>Demographics</h2>
<h3>Gender Distribution</h3>
<table>
<tr><th>Gender</th><th>Count</th><th>Percentage</th></tr>
''')
for gender, count in demographics['gender'].items():
percentage = (count / total_patients) * 100
f.write(f"<tr><td>{gender}</td><td>{count}</td><td>{percentage:.1f}%</td></tr>\n")
f.write('''
</table>
<h3>Age Statistics</h3>
<table>
''')
if demographics['age']:
min_age = min(demographics['age'])
max_age = max(demographics['age'])
avg_age = sum(demographics['age']) / len(demographics['age'])
f.write(f"<tr><td>Minimum Age</td><td>{min_age}</td></tr>\n")
f.write(f"<tr><td>Maximum Age</td><td>{max_age}</td></tr>\n")
f.write(f"<tr><td>Average Age</td><td>{avg_age:.1f}</td></tr>\n")
else:
f.write("<tr><td colspan='2'>No age data available</td></tr>\n")
f.write('''
</table>
<h3>Top Conditions</h3>
<table>
<tr><th>Condition</th><th>Count</th><th>Percentage of Patients</th></tr>
''')
for condition, count in sorted(condition_counts.items(), key=lambda x: x[1], reverse=True)[:15]:
percentage = (count / total_patients) * 100
f.write(f"<tr><td>{condition}</td><td>{count}</td><td>{percentage:.1f}%</td></tr>\n")
f.write('''
</table>
<h3>Top Medications</h3>
<table>
<tr><th>Medication</th><th>Count</th><th>Percentage of Patients</th></tr>
''')
for medication, count in sorted(medication_counts.items(), key=lambda x: x[1], reverse=True)[:15]:
percentage = (count / total_patients) * 100
f.write(f"<tr><td>{medication}</td><td>{count}</td><td>{percentage:.1f}%</td></tr>\n")
f.write('''
</table>
</div>
</body>
</html>''')
def create_csv_report(disease_name, output_dir, demographics, condition_counts, medication_counts, total_patients):
with open(os.path.join(output_dir, f"{disease_name.lower().replace(' ', '_')}_report.csv"), 'w') as f:
# Write header
f.write(f"Synthea Patient Analysis - {disease_name}\n")
f.write(f"Total patients analyzed,{total_patients}\n\n")
# Gender distribution
f.write("Gender Distribution\n")
f.write("Gender,Count,Percentage\n")
for gender, count in demographics['gender'].items():
percentage = (count / total_patients) * 100
f.write(f"{gender},{count},{percentage:.1f}%\n")
f.write("\n")
# Age statistics
f.write("Age Statistics\n")
if demographics['age']:
min_age = min(demographics['age'])
max_age = max(demographics['age'])
avg_age = sum(demographics['age']) / len(demographics['age'])
f.write(f"Minimum Age,{min_age}\n")
f.write(f"Maximum Age,{max_age}\n")
f.write(f"Average Age,{avg_age:.1f}\n")
else:
f.write("No age data available\n")
f.write("\n")
# Top conditions
f.write("Top Conditions\n")
f.write("Condition,Count,Percentage of Patients\n")
for condition, count in sorted(condition_counts.items(), key=lambda x: x[1], reverse=True)[:15]:
percentage = (count / total_patients) * 100
f.write(f"{condition},{count},{percentage:.1f}%\n")
f.write("\n")
# Top medications
f.write("Top Medications\n")
f.write("Medication,Count,Percentage of Patients\n")
for medication, count in sorted(medication_counts.items(), key=lambda x: x[1], reverse=True)[:15]:
percentage = (count / total_patients) * 100
f.write(f"{medication},{count},{percentage:.1f}%\n")
def create_json_report(disease_name, output_dir, demographics, condition_counts, medication_counts, total_patients):
# Prepare the report data
report_data = {
"disease": disease_name,
"total_patients": total_patients,
"demographics": {
"gender": {k: v for k, v in demographics['gender'].items()},
"race": {k: v for k, v in demographics['race'].items()},
"ethnicity": {k: v for k, v in demographics['ethnicity'].items()}
},
"age_statistics": {}
}
if demographics['age']:
report_data["age_statistics"] = {
"min_age": min(demographics['age']),
"max_age": max(demographics['age']),
"avg_age": sum(demographics['age']) / len(demographics['age'])
}
# Add top conditions
report_data["top_conditions"] = [
{"name": condition, "count": count, "percentage": (count / total_patients) * 100}
for condition, count in sorted(condition_counts.items(), key=lambda x: x[1], reverse=True)[:15]
]
# Add top medications
report_data["top_medications"] = [
{"name": medication, "count": count, "percentage": (count / total_patients) * 100}
for medication, count in sorted(medication_counts.items(), key=lambda x: x[1], reverse=True)[:15]
]
# Write to JSON file
with open(os.path.join(output_dir, f"{disease_name.lower().replace(' ', '_')}_report.json"), 'w') as f:
json.dump(report_data, f, indent=2)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Analyze Synthea patient data")
parser.add_argument("--disease", required=True, help="Disease name")
parser.add_argument("--input_dir", required=True, help="Input directory with FHIR files")
parser.add_argument("--output_dir", default=".", help="Output directory for reports")
parser.add_argument("--format", default="html", choices=["html", "csv", "json", "all"],
help="Output format (html, csv, json, or all)")
args = parser.parse_args()
analyze_patient_data(args.disease, args.input_dir, args.output_dir, args.format)

127
scripts/prepare_environment.sh Executable file
View File

@@ -0,0 +1,127 @@
#!/bin/bash
# prepare_environment.sh
#
# This script prepares the environment for running the Synthea pipeline.
# It rebuilds the Docker containers, ensures the directory structure is correct,
# and starts the necessary services.
set -e # Exit on error
# Display a header
echo "=================================================="
echo "Synthea All Diseases Pipeline - Environment Setup"
echo "=================================================="
# Check for Docker
if ! command -v docker &> /dev/null; then
echo "ERROR: Docker is not installed or not in the PATH."
echo "Please install Docker and try again."
exit 1
fi
# Check for docker-compose
if ! command -v docker-compose &> /dev/null; then
echo "ERROR: docker-compose is not installed or not in the PATH."
echo "Please install docker-compose and try again."
exit 1
fi
# Create necessary directories if they don't exist
echo "Creating required directories..."
mkdir -p module_generator
mkdir -p src/main/resources/modules
mkdir -p src/main/resources/disease
mkdir -p modules
mkdir -p output
# Check if the module_generator directory has the required scripts
if [ ! -f "module_generator/module_generator.py" ] || [ ! -f "module_generator/run_module_generator.py" ]; then
echo "ERROR: Required Python scripts not found in module_generator directory!"
# Check if they're in the python directory and we need to move them
if [ -d "python" ] && [ -f "python/module_generator.py" ] && [ -f "python/run_module_generator.py" ]; then
echo "Found scripts in python directory, moving them to module_generator directory..."
mkdir -p module_generator
mv python/module_generator.py module_generator/
mv python/run_module_generator.py module_generator/
# Copy README if exists
if [ -f "python/README_module_generator.md" ]; then
mv python/README_module_generator.md module_generator/
fi
else
echo "Scripts not found in python directory either. Please ensure the scripts are in the module_generator directory."
exit 1
fi
fi
# Make the Python scripts executable
chmod +x module_generator/module_generator.py
chmod +x module_generator/run_module_generator.py
# Create symlinks for convenience
ln -sf "$(pwd)/module_generator/run_module_generator.py" "$(pwd)/run_module_generator.py"
ln -sf "$(pwd)/module_generator/module_generator.py" "$(pwd)/module_generator.py"
# Create an empty disease_list.json if it doesn't exist
if [ ! -f "src/main/resources/disease_list.json" ]; then
echo "Creating empty disease_list.json..."
echo "[]" > src/main/resources/disease_list.json
fi
# Check if .env file exists
if [ ! -f ".env" ]; then
echo ".env file is missing. Creating from .env.example..."
if [ -f ".env.example" ]; then
cp .env.example .env
echo " Created .env from .env.example. Please edit it with your API key."
else
echo "WARNING: .env.example not found. Creating minimal .env file..."
echo "ANTHROPIC_API_KEY=your_api_key_here" > .env
fi
fi
# Stop any running containers
echo "Stopping any running containers..."
docker-compose down || true
# Rebuild the containers
echo "Building Docker containers..."
docker-compose build
# Start the Synthea container
echo "Starting Synthea container..."
docker-compose up -d synthea
# Give the container a moment to start
echo "Waiting for Synthea container to be ready..."
sleep 10
# Check if the container is healthy
CONTAINER_ID=$(docker-compose ps -q synthea)
if [ -z "$CONTAINER_ID" ]; then
echo "ERROR: Failed to start Synthea container."
exit 1
fi
# Check if the container is using proper health checks
HEALTH_STATUS=$(docker inspect --format='{{.State.Health.Status}}' $CONTAINER_ID 2>/dev/null || echo "unknown")
if [ "$HEALTH_STATUS" != "healthy" ] && [ "$HEALTH_STATUS" != "unknown" ]; then
echo "WARNING: Synthea container is not reporting as healthy (status: $HEALTH_STATUS)."
echo "It may take some time for the container to become fully operational."
echo "You can proceed, but the pipeline may fail if the container is not ready."
fi
# Check if we should generate modules
if [ "$1" == "--generate-modules" ]; then
echo "Starting module generator..."
docker-compose --profile generator up module-generator
fi
echo "=================================================="
echo "Environment is ready!"
echo ""
echo "To generate patients for a disease module:"
echo "nextflow run main.nf --disease_name \"Disease Name\" --generate_patients true"
echo ""
echo "To generate a new module and patients:"
echo "nextflow run main.nf --disease_name \"Disease Name\" --force_generate true --generate_patients true"
echo "=================================================="

77
scripts/run_module.py Normal file
View File

@@ -0,0 +1,77 @@
#!/usr/bin/env python3
import os
import sys
import json
import anthropic
DISEASE_NAME = "Excessive frequent and irregular menstruation"
OUTPUT_FILE = "excessive_frequent_and_irregular_menstruation.json"
# Initialize the Anthropic client with your API key
client = anthropic.Anthropic(
# This is the default and can be omitted
api_key=os.environ.get("ANTHROPIC_API_KEY"),
)
# Define the prompt for generating the module
def generate_module_prompt(disease_name):
return f"""
You are a medical expert creating a disease module for the Synthea patient simulation system.
I need you to create a structured JSON module for {disease_name}.
The module will be used to simulate patients with this condition in the Synthea healthcare simulation system.
The JSON should follow the Synthea module format which includes:
1. Basic module information (name, remarks)
2. States representing the progression of the disease
3. Transitions between states
4. Guard conditions based on patient attributes where appropriate
5. Care plans and medications that would be prescribed
Your output should be valid JSON that follows the Synthea module structure precisely. Format it as a complete,
well-structured Synthea module. Make sure it's medically accurate and includes all relevant clinical details,
treatment options, and disease progression patterns.
Output only the JSON with no additional commentary or markdown formatting. The output will be directly saved as a file.
"""
print(f"Generating module for {DISEASE_NAME}...")
try:
# Send a message to Claude
message = client.messages.create(
model="claude-3-7-sonnet-20250219",
max_tokens=4000,
temperature=0,
messages=[
{"role": "user", "content": generate_module_prompt(DISEASE_NAME)}
]
)
# Extract the JSON from the response
module_json = message.content[0].text
# Find the first '{' and last '}' to extract just the JSON part
start = module_json.find('{')
end = module_json.rfind('}') + 1
if start >= 0 and end > start:
module_json = module_json[start:end]
# Parse and format the JSON
parsed = json.loads(module_json)
formatted_json = json.dumps(parsed, indent=2)
# Write to file
with open(OUTPUT_FILE, 'w') as f:
f.write(formatted_json)
print(f"✅ Successfully generated module and saved to {OUTPUT_FILE}")
except Exception as e:
print(f"Error: {e}")
# Save the raw response for debugging
with open("error_output.txt", 'w') as f:
f.write(str(e))
print("Error details saved to error_output.txt")
sys.exit(1)

182
scripts/run_pipeline.sh Executable file
View File

@@ -0,0 +1,182 @@
#!/bin/bash
# run_pipeline.sh
#
# This script runs the Nextflow pipeline for generating disease modules and synthetic patients
set -e # Exit on error
# Default values
DISEASE_NAME=""
FORCE_GENERATE=false
GENERATE_PATIENTS=false
POPULATION=100
GENDER=0.5
MIN_AGE=0
MAX_AGE=90
SEED=""
ANALYZE_DATA=false
REPORT_FORMAT="html"
VERIFY_DOCKER=true
# Parse command line arguments
function show_help {
echo "Usage: $0 [options] --disease \"Disease Name\""
echo ""
echo "Options:"
echo " --disease, -d NAME Disease name to generate a module for (required)"
echo " --force-generate, -f Force regeneration of disease module even if it exists"
echo " --patients, -p Generate synthetic patients (default: false)"
echo " --population, -n NUM Number of patients to generate (default: 100)"
echo " --gender, -g VALUE Gender distribution (0-1 for % female, default: 0.5)"
echo " --min-age, -a NUM Minimum patient age (default: 0)"
echo " --max-age, -m NUM Maximum patient age (default: 90)"
echo " --seed, -s SEED Random seed for reproducibility"
echo " --analyze, -A Analyze patient data after generation"
echo " --report-format, -r FMT Report format for analysis (html, json, csv, default: html)"
echo " --skip-docker-check Skip Docker container verification"
echo " --help, -h Show this help message"
echo ""
echo "Example:"
echo " $0 --disease \"Multiple Sclerosis\" --patients --population 50"
exit 1
}
# Parse arguments
while [[ $# -gt 0 ]]; do
case "$1" in
--disease|-d)
DISEASE_NAME="$2"
shift 2
;;
--force-generate|-f)
FORCE_GENERATE=true
shift
;;
--patients|-p)
GENERATE_PATIENTS=true
shift
;;
--population|-n)
POPULATION="$2"
shift 2
;;
--gender|-g)
GENDER="$2"
shift 2
;;
--min-age|-a)
MIN_AGE="$2"
shift 2
;;
--max-age|-m)
MAX_AGE="$2"
shift 2
;;
--seed|-s)
SEED="$2"
shift 2
;;
--analyze|-A)
ANALYZE_DATA=true
shift
;;
--report-format|-r)
REPORT_FORMAT="$2"
shift 2
;;
--skip-docker-check)
VERIFY_DOCKER=false
shift
;;
--help|-h)
show_help
;;
*)
echo "Unknown option: $1"
show_help
;;
esac
done
# Check if disease name is provided
if [ -z "$DISEASE_NAME" ]; then
echo "ERROR: Disease name is required!"
show_help
fi
# Check if Docker container is running if we need to generate patients
if [ "$VERIFY_DOCKER" = true ] && [ "$GENERATE_PATIENTS" = true ]; then
CONTAINER_RUNNING=$(docker ps | grep synthea | wc -l)
if [ "$CONTAINER_RUNNING" -eq 0 ]; then
echo "No Synthea Docker containers are running!"
echo "Running environment setup script to start containers..."
if [ -f "./scripts/prepare_environment.sh" ]; then
./scripts/prepare_environment.sh
elif [ -f "./prepare_environment.sh" ]; then
./prepare_environment.sh
else
echo "ERROR: prepare_environment.sh not found!"
exit 1
fi
else
echo "Synthea Docker container is running. Proceeding with pipeline execution."
fi
fi
# Create params.json file with our configuration
echo "Creating params.json file with pipeline configuration..."
cat > params.json << EOF
{
"disease_name": "$DISEASE_NAME",
"modules_dir": "modules",
"output_dir": "output",
"generate_patients": $GENERATE_PATIENTS,
"population": $POPULATION,
"gender": $GENDER,
"min_age": $MIN_AGE,
"max_age": $MAX_AGE,
"analyze_patient_data": $ANALYZE_DATA,
"report_format": "$REPORT_FORMAT",
"force_generate": $FORCE_GENERATE,
"publish_dir": "published_output"
EOF
# Add seed if provided
if [ ! -z "$SEED" ]; then
echo ", \"seed\": $SEED" >> params.json
fi
# Close JSON object
echo "}" >> params.json
# Display execution details
echo "=================================================="
echo "Running Synthea Pipeline for: $DISEASE_NAME"
echo "Generate patients: $GENERATE_PATIENTS"
if [ "$GENERATE_PATIENTS" = true ]; then
echo "Population: $POPULATION"
echo "Gender ratio (proportion female): $GENDER"
echo "Age range: $MIN_AGE-$MAX_AGE"
if [ ! -z "$SEED" ]; then
echo "Random seed: $SEED"
fi
fi
echo "Force module generation: $FORCE_GENERATE"
echo "Analyze patient data: $ANALYZE_DATA"
echo "=================================================="
# Execute the Nextflow command
echo "Starting Nextflow pipeline..."
nextflow run main.nf
echo ""
echo "Pipeline execution complete!"
if [ "$GENERATE_PATIENTS" = true ]; then
echo "Check the 'output' directory and 'published_output/$DISEASE_NAME_NORMALIZED' for generated patient data."
if [ "$ANALYZE_DATA" = true ]; then
echo "Analysis reports can be found in 'published_output/$DISEASE_NAME_NORMALIZED/analysis'."
fi
fi
echo "Generated modules can be found in the 'modules' directory and 'published_output/modules'."
echo ""

99
scripts/simple_module.py Executable file
View File

@@ -0,0 +1,99 @@
#!/usr/bin/env python3
import os
import sys
import json
import anthropic
DISEASE_NAME = "Excessive frequent and irregular menstruation"
OUTPUT_FILE = "excessive_frequent_and_irregular_menstruation.json"
# Initialize the Anthropic client
client = anthropic.Anthropic()
print(f"Generating module for {DISEASE_NAME}...")
try:
# Send a message to Claude
message = client.messages.create(
model="claude-3-7-sonnet-20250219",
max_tokens=4000,
temperature=0,
messages=[
{"role": "user", "content": f"""Create a Synthea disease module for {DISEASE_NAME} in JSON format.
The module should follow this structure:
{{
"name": "Module Name",
"remarks": [
"Description of the module"
],
"states": {{
"Initial": {{
"type": "Initial",
"direct_transition": "Next State"
}},
"Terminal": {{
"type": "Terminal"
}}
// Additional states with appropriate transitions
}}
}}
Make sure the JSON is properly formatted with no syntax errors.
Do not include any markdown formatting, comments, or explanations outside the JSON.
Output only the valid JSON object."""}
]
)
# Extract the JSON from the response
module_json = message.content[0].text
# Save the raw response for debugging
with open(f"{OUTPUT_FILE}.raw", "w") as f:
f.write(module_json)
print(f"Raw response saved to {OUTPUT_FILE}.raw")
# Find the first { and last } to extract just the JSON part
start = module_json.find("{")
end = module_json.rfind("}") + 1
if start >= 0 and end > start:
module_json = module_json[start:end]
# Fix common JSON issues
try:
# Manual cleaning of known JSON issues
# Find and remove lines with invalid syntax
cleaned_lines = []
for line in module_json.split('\n'):
# Skip lines with "{%" or any other invalid JSON syntax
if "{%" in line or "%}" in line or "//" in line:
print(f"Removing invalid line: {line}")
continue
cleaned_lines.append(line)
cleaned_json = '\n'.join(cleaned_lines)
# Try to parse and fix the JSON
parsed = json.loads(cleaned_json)
formatted_json = json.dumps(parsed, indent=2)
# Write to file
with open(OUTPUT_FILE, "w") as f:
f.write(formatted_json)
print(f"Successfully generated module and saved to {OUTPUT_FILE}")
except json.JSONDecodeError as e:
print(f"JSON parsing error: {e}")
print("Attempting secondary cleaning method...")
# Write the error details for debugging
with open(f"{OUTPUT_FILE}.error", "w") as f:
f.write(f"Error: {str(e)}\n\n")
f.write("JSON that failed to parse:\n")
f.write(module_json)
except Exception as e:
print(f"Error: {e}")
sys.exit(1)

1
scripts/test.py Normal file
View File

@@ -0,0 +1 @@
import anthropic; import os; client = anthropic.Anthropic(); print(client.messages.create(model="claude-3-7-sonnet-20250219", max_tokens=1000, messages=[{"role": "user", "content": "Hello"}]).content[0].text)

123
scripts/test_module_exists.py Executable file
View File

@@ -0,0 +1,123 @@
#!/usr/bin/env python3
"""
Simple script to check if a module exists for a given disease and generate it if not.
"""
import os
import sys
import json
import subprocess
import re
# Constants
DISEASE_NAME = sys.argv[1] if len(sys.argv) > 1 else "Excessive frequent and irregular menstruation"
MODULES_DIR = "src/main/resources/modules"
RUN_MODULE_GENERATOR_PATH = "src/main/python/run_module_generator.py"
DISEASE_LIST_PATH = "src/main/resources/disease_list.json"
# Function to normalize disease name for filenames
def normalize_filename(name):
"""Convert disease name to normalized filename format."""
filename = name.lower()
filename = re.sub(r'[^a-zA-Z0-9]', '_', filename)
filename = re.sub(r'_+', '_', filename)
filename = filename.strip('_')
return filename
# Main function
def main():
print(f"Checking if module exists for: {DISEASE_NAME}")
# Normalize disease name for filename
normalized_name = normalize_filename(DISEASE_NAME)
module_path = os.path.join(MODULES_DIR, f"{normalized_name}.json")
# Check if module already exists
if os.path.exists(module_path):
print(f"✅ Module already exists at: {module_path}")
return
print(f"❌ Module not found at: {module_path}")
print(f"Creating disease list entry for {DISEASE_NAME}...")
# Create temporary disease list with just this disease
create_disease_list(DISEASE_NAME)
# Run the module generator
print(f"Running module generator for {DISEASE_NAME}...")
try:
result = subprocess.run(
[sys.executable, RUN_MODULE_GENERATOR_PATH, "--batch-size", "1"],
capture_output=True,
text=True,
check=True
)
print("Module generator output:")
print(result.stdout)
# Check if module was created
if os.path.exists(module_path):
print(f"✅ Module created successfully at: {module_path}")
else:
print(f"❌ Module generation failed, file not found at: {module_path}")
print("Error output:")
print(result.stderr)
except subprocess.CalledProcessError as e:
print(f"Error running module generator: {e}")
print("STDOUT:")
print(e.stdout)
print("STDERR:")
print(e.stderr)
def create_disease_list(disease_name):
"""Create a temporary disease list with just the requested disease."""
disease_list = []
# Try to read original disease list if it exists
if os.path.exists(DISEASE_LIST_PATH):
try:
with open(DISEASE_LIST_PATH, 'r') as f:
original_diseases = json.load(f)
# Check if our disease already exists
name_lower = disease_name.lower()
for disease in original_diseases:
if disease.get("disease_name", "").lower() == name_lower:
disease_list.append(disease)
print(f"Found existing disease entry for '{disease_name}'")
break
else:
# Disease not found in list
disease_list.append({
"id": "", # ICD-10 code (empty as we don't have it)
"disease_name": disease_name,
"ICD-10_name": disease_name
})
print(f"Created new disease entry for '{disease_name}'")
except Exception as e:
print(f"Error reading disease list: {e}")
# Create new entry
disease_list.append({
"id": "",
"disease_name": disease_name,
"ICD-10_name": disease_name
})
else:
# Create new entry
disease_list.append({
"id": "",
"disease_name": disease_name,
"ICD-10_name": disease_name
})
print(f"Created new disease list with '{disease_name}'")
# Save disease list
os.makedirs(os.path.dirname(DISEASE_LIST_PATH), exist_ok=True)
with open(DISEASE_LIST_PATH, 'w') as f:
json.dump(disease_list, f, indent=2)
print(f"Saved disease list with {len(disease_list)} entries.")
if __name__ == "__main__":
main()

305
scripts/validate_module.py Executable file
View File

@@ -0,0 +1,305 @@
#!/usr/bin/env python3
"""
Disease Module Validator for Synthea
This script validates a Synthea disease module for JSON correctness and
checks for common issues in the module structure.
Usage:
python validate_module.py <path_to_module.json>
"""
import json
import sys
import os
import re
def color_text(text, color_code):
"""Add color to terminal output"""
return f"\033[{color_code}m{text}\033[0m"
def red(text):
return color_text(text, "91")
def green(text):
return color_text(text, "92")
def yellow(text):
return color_text(text, "93")
def check_required_fields(module_json):
"""Check if the module has all required fields"""
required_fields = ['name', 'states', 'gmf_version']
missing_fields = []
for field in required_fields:
if field not in module_json:
missing_fields.append(field)
return missing_fields
def check_transitions(module_json):
"""Check if all transitions are valid"""
errors = []
# Skip if no states
if 'states' not in module_json:
return ["No 'states' field found"]
states = module_json['states']
state_names = set(states.keys())
# Check each state
for state_name, state_config in states.items():
# Skip Terminal states (they should not have transitions)
if state_config.get('type') == 'Terminal':
continue
# Check if the state has any transition
transition_found = False
transition_types = ['direct_transition', 'distributed_transition',
'conditional_transition', 'complex_transition']
for transition_type in transition_types:
if transition_type in state_config:
transition_found = True
# Check direct transitions
if transition_type == 'direct_transition':
target = state_config[transition_type]
if target not in state_names:
errors.append(f"State '{state_name}' has invalid direct_transition to non-existent state '{target}'")
# Check distributed transitions
elif transition_type == 'distributed_transition':
for transition in state_config[transition_type]:
if 'transition' in transition and transition['transition'] not in state_names:
errors.append(f"State '{state_name}' has invalid distributed_transition to non-existent state '{transition['transition']}'")
# Check conditional transitions
elif transition_type == 'conditional_transition':
for transition in state_config[transition_type]:
if 'transition' in transition and transition['transition'] not in state_names:
errors.append(f"State '{state_name}' has invalid conditional_transition to non-existent state '{transition['transition']}'")
# Check complex transitions
elif transition_type == 'complex_transition':
for transition in state_config[transition_type]:
if 'transition' in transition and transition['transition'] not in state_names:
errors.append(f"State '{state_name}' has invalid complex_transition to non-existent state '{transition['transition']}'")
if 'distributions' in transition:
for dist in transition['distributions']:
if 'transition' in dist and dist['transition'] not in state_names:
errors.append(f"State '{state_name}' has invalid complex_transition distribution to non-existent state '{dist['transition']}'")
if not transition_found and state_config.get('type') != 'Terminal':
errors.append(f"State '{state_name}' has no transition defined")
return errors
def check_codes(module_json):
"""Check if medical codes are properly formatted"""
warnings = []
json_str = json.dumps(module_json)
# Check for codes in common formats
code_patterns = {
'SNOMED-CT': r'"system":\s*"SNOMED-CT",\s*"code":\s*"[0-9]+"',
'LOINC': r'"system":\s*"LOINC",\s*"code":\s*"[0-9\\-]+"',
'RxNorm': r'"system":\s*"RxNorm",\s*"code":\s*"[0-9]+"',
'ICD-10': r'"system":\s*"ICD-10",\s*"code":\s*"[A-Z][0-9]+"'
}
for code_type, pattern in code_patterns.items():
if not re.search(pattern, json_str):
warnings.append(f"No {code_type} codes found. This may be normal depending on the module.")
return warnings
def check_prevalence(module_json):
"""Check if prevalence information exists"""
warnings = []
json_str = json.dumps(module_json)
# Check for prevalence patterns
if not any(pat in json_str for pat in ['"prevalence"', 'incidence', 'probability']):
warnings.append("No prevalence, incidence, or probability data found. This may affect realism.")
return warnings
def check_circular_references(module_json):
"""Check for circular references between states"""
errors = []
# Skip if no states
if 'states' not in module_json:
return []
states = module_json['states']
# Build a directed graph representation
graph = {}
for state_name in states:
graph[state_name] = []
# Add edges to the graph
for state_name, state_config in states.items():
# Add direct transitions
if 'direct_transition' in state_config:
target = state_config['direct_transition']
graph[state_name].append(target)
# Add distributed transitions
if 'distributed_transition' in state_config:
for transition in state_config['distributed_transition']:
if 'transition' in transition:
graph[state_name].append(transition['transition'])
# Add conditional transitions
if 'conditional_transition' in state_config:
for transition in state_config['conditional_transition']:
if 'transition' in transition:
graph[state_name].append(transition['transition'])
# Add complex transitions
if 'complex_transition' in state_config:
for transition in state_config['complex_transition']:
if 'transition' in transition:
graph[state_name].append(transition['transition'])
# Check for cycles in the graph (simplified check)
visited = set()
path = []
def dfs(node):
visited.add(node)
path.append(node)
for neighbor in graph[node]:
if neighbor in path:
# Found a cycle
cycle_start = path.index(neighbor)
errors.append(f"Circular reference detected: {' -> '.join(path[cycle_start:] + [neighbor])}")
elif neighbor not in visited:
dfs(neighbor)
path.pop()
# Run DFS from all states to find cycles
for state_name in states:
if state_name not in visited:
dfs(state_name)
return errors
def main():
if len(sys.argv) != 2:
print(f"Usage: python {sys.argv[0]} <path_to_module.json>")
sys.exit(1)
module_path = sys.argv[1]
if not os.path.exists(module_path):
print(red(f"Error: File {module_path} does not exist"))
sys.exit(1)
try:
with open(module_path, 'r') as f:
content = f.read()
# First check for valid JSON
try:
module_json = json.loads(content)
print(green("✓ Valid JSON structure"))
except json.JSONDecodeError as e:
print(red(f"✗ Invalid JSON: {e}"))
# Try to fix common issues
print(yellow("Attempting to fix common JSON issues..."))
# Fix trailing commas
fixed_content = re.sub(r',\s*}', '}', content)
fixed_content = re.sub(r',\s*]', ']', fixed_content)
# Count braces
open_braces = fixed_content.count('{')
close_braces = fixed_content.count('}')
if open_braces > close_braces:
print(yellow(f"Adding {open_braces - close_braces} missing closing braces"))
fixed_content += '}' * (open_braces - close_braces)
elif close_braces > open_braces:
print(yellow(f"Removing {close_braces - open_braces} excess closing braces"))
for _ in range(close_braces - open_braces):
fixed_content = fixed_content.rstrip().rstrip('}') + '}'
try:
module_json = json.loads(fixed_content)
print(green("✓ Fixed JSON issues successfully"))
# Write the fixed content back to the file
with open(module_path, 'w') as f:
f.write(json.dumps(module_json, indent=2))
except json.JSONDecodeError as e:
print(red(f"✗ Could not fix JSON: {e}"))
sys.exit(1)
# Check required fields
missing_fields = check_required_fields(module_json)
if missing_fields:
print(red(f"✗ Missing required fields: {', '.join(missing_fields)}"))
else:
print(green("✓ All required fields present"))
# Check for invalid transitions
transition_errors = check_transitions(module_json)
if transition_errors:
print(red("✗ Invalid transitions found:"))
for error in transition_errors:
print(red(f" - {error}"))
else:
print(green("✓ All transitions valid"))
# Check for circular references
circular_errors = check_circular_references(module_json)
if circular_errors:
print(red("✗ Circular references found:"))
for error in circular_errors:
print(red(f" - {error}"))
else:
print(green("✓ No circular references detected"))
# Check for medical codes
code_warnings = check_codes(module_json)
if code_warnings:
print(yellow("⚠ Possible code issues:"))
for warning in code_warnings:
print(yellow(f" - {warning}"))
else:
print(green("✓ Medical codes look good"))
# Check for prevalence information
prevalence_warnings = check_prevalence(module_json)
if prevalence_warnings:
print(yellow("⚠ Possible prevalence issues:"))
for warning in prevalence_warnings:
print(yellow(f" - {warning}"))
else:
print(green("✓ Prevalence information looks good"))
# Display module stats
print("\nModule Statistics:")
print(f"- Name: {module_json.get('name', 'Unknown')}")
print(f"- GMF Version: {module_json.get('gmf_version', 'Unknown')}")
print(f"- States: {len(module_json.get('states', {}))}")
print(f"- Remarks: {len(module_json.get('remarks', []))}")
except Exception as e:
print(red(f"Error: {e}"))
sys.exit(1)
if __name__ == "__main__":
main()

77
simple.nf Normal file
View File

@@ -0,0 +1,77 @@
#!/usr/bin/env nextflow
nextflow.enable.dsl=2
// Default parameters
params.disease_name = "Diabetes" // Default disease name
params.output_dir = "output" // Output directory
params.modules_dir = "modules" // Directory for module files
// Process to generate synthetic patients
process generatePatients {
publishDir "${params.output_dir}/${params.disease_name.toLowerCase().replaceAll(' ', '_')}", mode: 'copy'
input:
path moduleFile
output:
path "**"
script:
"""
echo "Module file: ${moduleFile}"
echo "Disease: ${params.disease_name}"
# Check if Docker is available
if command -v docker &>/dev/null; then
echo "Docker is available, looking for Synthea container..."
# Find the Synthea container
container_id=\$(docker ps --format '{{.ID}}' --filter "name=synthea" | head -1)
if [ -n "\$container_id" ]; then
echo "Using Synthea container \$container_id"
# Copy module to container
docker exec \$container_id mkdir -p /app/modules
docker cp "${moduleFile}" \$container_id:/app/modules/
# Run Synthea with minimal parameters
docker exec \$container_id bash -c "cd /app && ./run_synthea -p 1 -m ${params.disease_name.toLowerCase().replaceAll(' ', '_')}"
# Copy output from container
docker cp \$container_id:/app/output/fhir ./ || mkdir -p ./fhir
docker cp \$container_id:/app/output/metadata ./ || mkdir -p ./metadata
echo "Completed patient generation"
else
echo "No Synthea container found, creating mock output for testing"
mkdir -p ./fhir ./metadata
echo "Mock FHIR data for ${params.disease_name}" > ./fhir/mock_patient.json
echo "Mock metadata for ${params.disease_name}" > ./metadata/mock_stats.json
fi
else
echo "Docker not available, creating mock output for testing"
mkdir -p ./fhir ./metadata
echo "Mock FHIR data for ${params.disease_name}" > ./fhir/mock_patient.json
echo "Mock metadata for ${params.disease_name}" > ./metadata/mock_stats.json
fi
"""
}
// Define workflow
workflow {
// Prepare module file
moduleFilename = params.disease_name.toLowerCase().replaceAll(' ', '_') + '.json'
moduleFile = file("${params.modules_dir}/${moduleFilename}")
if (!moduleFile.exists()) {
error "Module file not found: ${moduleFile}"
}
// Create a channel with the module file
moduleChannel = Channel.fromPath(moduleFile)
// Generate patients
generatePatients(moduleChannel)
}

View File

@@ -0,0 +1,8 @@
[
{
"disease_name": "Hypertension",
"id": "X99",
"ICD-10_name": "Hypertension",
"snomed": "123456789"
}
]

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,32 @@
[
{
"disease_name": "Multiple Sclerosis",
"id": "G35",
"ICD-10_name": "Multiple sclerosis",
"snomed": "24700007"
},
{
"disease_name": "Parkinson's Disease",
"id": "G20",
"ICD-10_name": "Parkinson's disease",
"snomed": "49049000"
},
{
"disease_name": "Migraine",
"id": "G43",
"ICD-10_name": "Migraine",
"snomed": "37796009"
},
{
"disease_name": "Epilepsy",
"id": "G40",
"ICD-10_name": "Epilepsy",
"snomed": "84757009"
},
{
"disease_name": "Alzheimer's Disease",
"id": "G30",
"ICD-10_name": "Alzheimer's disease",
"snomed": "26929004"
}
]

View File

@@ -0,0 +1,32 @@
[
{
"disease_name": "Hypertension",
"id": "I10",
"ICD-10_name": "Essential (primary) hypertension",
"snomed": "38341003"
},
{
"disease_name": "Migraine",
"id": "G43",
"ICD-10_name": "Migraine",
"snomed": "37796009"
},
{
"disease_name": "Osteoarthritis",
"id": "M19",
"ICD-10_name": "Other and unspecified osteoarthritis",
"snomed": "396275006"
},
{
"disease_name": "Gastroesophageal Reflux Disease",
"id": "K21",
"ICD-10_name": "Gastro-esophageal reflux disease",
"snomed": "235595009"
},
{
"disease_name": "Urinary Tract Infection",
"id": "N39.0",
"ICD-10_name": "Urinary tract infection, site not specified",
"snomed": "68566005"
}
]

View File

@@ -0,0 +1,6 @@
# Disease Module Progress
## Completed Modules
## Planned Modules

View File

@@ -0,0 +1,403 @@
{
"name": "Acne Vulgaris",
"remarks": [
"This module models the diagnosis and treatment of Acne Vulgaris (ICD-10 code: 20002_1548).",
"Acne vulgaris is a chronic inflammatory skin condition that primarily affects adolescents and young adults.",
"It is characterized by comedones (blackheads and whiteheads), papules, pustules, nodules, and cysts.",
"Category: Skin and Subcutaneous Tissue"
],
"states": {
"Initial": {
"type": "Initial",
"direct_transition": "Age_Guard"
},
"Age_Guard": {
"type": "Guard",
"allow": {
"age_range": {
"low": 10,
"high": 30
}
},
"direct_transition": "Acne_Onset"
},
"Acne_Onset": {
"type": "Delay",
"range": {
"low": 0,
"high": 60,
"unit": "months"
},
"direct_transition": "Acne_Severity_Determination"
},
"Acne_Severity_Determination": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.5,
"transition": "Mild_Acne"
},
{
"distribution": 0.3,
"transition": "Moderate_Acne"
},
{
"distribution": 0.2,
"transition": "Severe_Acne"
}
]
},
"Mild_Acne": {
"type": "ConditionOnset",
"target_encounter": "Acne_Diagnosis_Encounter",
"codes": [
{
"system": "ICD-10-CM",
"code": "20002_1548",
"display": "Acne vulgaris"
}
],
"assign_to_attribute": "acne",
"direct_transition": "Acne_Diagnosis_Encounter"
},
"Moderate_Acne": {
"type": "ConditionOnset",
"target_encounter": "Acne_Diagnosis_Encounter",
"codes": [
{
"system": "ICD-10-CM",
"code": "20002_1548",
"display": "Acne vulgaris"
}
],
"assign_to_attribute": "acne",
"direct_transition": "Acne_Diagnosis_Encounter"
},
"Severe_Acne": {
"type": "ConditionOnset",
"target_encounter": "Acne_Diagnosis_Encounter",
"codes": [
{
"system": "ICD-10-CM",
"code": "20002_1548",
"display": "Acne vulgaris"
}
],
"assign_to_attribute": "acne",
"direct_transition": "Acne_Diagnosis_Encounter"
},
"Acne_Diagnosis_Encounter": {
"type": "Encounter",
"encounter_class": "ambulatory",
"reason": "acne",
"codes": [
{
"system": "SNOMED-CT",
"code": "185347001",
"display": "Encounter for problem"
}
],
"direct_transition": "Acne_Diagnosis"
},
"Acne_Diagnosis": {
"type": "Procedure",
"target_encounter": "Acne_Diagnosis_Encounter",
"reason": "acne",
"codes": [
{
"system": "SNOMED-CT",
"code": "76058001",
"display": "Assessment of skin condition"
}
],
"conditional_transition": [
{
"condition": {
"condition_type": "PriorState",
"name": "Mild_Acne"
},
"transition": "Prescribe_Mild_Treatment"
},
{
"condition": {
"condition_type": "PriorState",
"name": "Moderate_Acne"
},
"transition": "Prescribe_Moderate_Treatment"
},
{
"condition": {
"condition_type": "PriorState",
"name": "Severe_Acne"
},
"transition": "Prescribe_Severe_Treatment"
}
]
},
"Prescribe_Mild_Treatment": {
"type": "MedicationOrder",
"target_encounter": "Acne_Diagnosis_Encounter",
"reason": "acne",
"codes": [
{
"system": "RxNorm",
"code": "1043400",
"display": "Benzoyl Peroxide 5% Topical Gel"
}
],
"direct_transition": "Lifestyle_Education"
},
"Prescribe_Moderate_Treatment": {
"type": "MedicationOrder",
"target_encounter": "Acne_Diagnosis_Encounter",
"reason": "acne",
"codes": [
{
"system": "RxNorm",
"code": "1043400",
"display": "Benzoyl Peroxide 5% Topical Gel"
}
],
"direct_transition": "Prescribe_Topical_Antibiotic"
},
"Prescribe_Topical_Antibiotic": {
"type": "MedicationOrder",
"target_encounter": "Acne_Diagnosis_Encounter",
"reason": "acne",
"codes": [
{
"system": "RxNorm",
"code": "1153378",
"display": "Clindamycin 1% Topical Solution"
}
],
"direct_transition": "Lifestyle_Education"
},
"Prescribe_Severe_Treatment": {
"type": "MedicationOrder",
"target_encounter": "Acne_Diagnosis_Encounter",
"reason": "acne",
"codes": [
{
"system": "RxNorm",
"code": "197698",
"display": "Isotretinoin 20 MG Oral Capsule"
}
],
"direct_transition": "Lifestyle_Education"
},
"Lifestyle_Education": {
"type": "Procedure",
"target_encounter": "Acne_Diagnosis_Encounter",
"reason": "acne",
"codes": [
{
"system": "SNOMED-CT",
"code": "409063005",
"display": "Counseling"
}
],
"direct_transition": "End_Diagnosis_Encounter"
},
"End_Diagnosis_Encounter": {
"type": "EncounterEnd",
"direct_transition": "Treatment_Period"
},
"Treatment_Period": {
"type": "Delay",
"range": {
"low": 4,
"high": 12,
"unit": "weeks"
},
"direct_transition": "Follow_Up_Encounter"
},
"Follow_Up_Encounter": {
"type": "Encounter",
"encounter_class": "ambulatory",
"reason": "acne",
"codes": [
{
"system": "SNOMED-CT",
"code": "390906007",
"display": "Follow-up encounter"
}
],
"direct_transition": "Assess_Treatment_Response"
},
"Assess_Treatment_Response": {
"type": "Procedure",
"target_encounter": "Follow_Up_Encounter",
"reason": "acne",
"codes": [
{
"system": "SNOMED-CT",
"code": "76058001",
"display": "Assessment of skin condition"
}
],
"distributed_transition": [
{
"distribution": 0.7,
"transition": "Treatment_Successful"
},
{
"distribution": 0.3,
"transition": "Treatment_Adjustment_Needed"
}
]
},
"Treatment_Successful": {
"type": "Simple",
"direct_transition": "End_Follow_Up_Encounter"
},
"Treatment_Adjustment_Needed": {
"type": "Simple",
"conditional_transition": [
{
"condition": {
"condition_type": "PriorState",
"name": "Mild_Acne"
},
"transition": "Escalate_To_Moderate_Treatment"
},
{
"condition": {
"condition_type": "PriorState",
"name": "Moderate_Acne"
},
"transition": "Escalate_To_Severe_Treatment"
},
{
"condition": {
"condition_type": "PriorState",
"name": "Severe_Acne"
},
"transition": "Adjust_Severe_Treatment"
}
]
},
"Escalate_To_Moderate_Treatment": {
"type": "MedicationOrder",
"target_encounter": "Follow_Up_Encounter",
"reason": "acne",
"codes": [
{
"system": "RxNorm",
"code": "1153378",
"display": "Clindamycin 1% Topical Solution"
}
],
"direct_transition": "End_Follow_Up_Encounter"
},
"Escalate_To_Severe_Treatment": {
"type": "MedicationOrder",
"target_encounter": "Follow_Up_Encounter",
"reason": "acne",
"codes": [
{
"system": "RxNorm",
"code": "197698",
"display": "Isotretinoin 20 MG Oral Capsule"
}
],
"direct_transition": "End_Follow_Up_Encounter"
},
"Adjust_Severe_Treatment": {
"type": "MedicationOrder",
"target_encounter": "Follow_Up_Encounter",
"reason": "acne",
"codes": [
{
"system": "RxNorm",
"code": "197699",
"display": "Isotretinoin 40 MG Oral Capsule"
}
],
"direct_transition": "End_Follow_Up_Encounter"
},
"End_Follow_Up_Encounter": {
"type": "EncounterEnd",
"direct_transition": "Check_For_Complications"
},
"Check_For_Complications": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.05,
"transition": "Develop_Scarring"
},
{
"distribution": 0.95,
"transition": "Continued_Treatment"
}
]
},
"Develop_Scarring": {
"type": "ConditionOnset",
"target_encounter": "Complication_Encounter",
"codes": [
{
"system": "SNOMED-CT",
"code": "429127001",
"display": "Acne scar"
}
],
"direct_transition": "Complication_Encounter"
},
"Complication_Encounter": {
"type": "Encounter",
"encounter_class": "ambulatory",
"codes": [
{
"system": "SNOMED-CT",
"code": "185347001",
"display": "Encounter for problem"
}
],
"direct_transition": "Treat_Scarring"
},
"Treat_Scarring": {
"type": "Procedure",
"target_encounter": "Complication_Encounter",
"codes": [
{
"system": "SNOMED-CT",
"code": "277358003",
"display": "Topical treatment"
}
],
"direct_transition": "End_Complication_Encounter"
},
"End_Complication_Encounter": {
"type": "EncounterEnd",
"direct_transition": "Continued_Treatment"
},
"Continued_Treatment": {
"type": "Delay",
"range": {
"low": 3,
"high": 6,
"unit": "months"
},
"distributed_transition": [
{
"distribution": 0.7,
"transition": "Acne_Resolves"
},
{
"distribution": 0.3,
"transition": "Follow_Up_Encounter"
}
]
},
"Acne_Resolves": {
"type": "ConditionEnd",
"referenced_by_attribute": "acne",
"direct_transition": "Terminal"
},
"Terminal": {
"type": "Terminal"
}
}
}

View File

@@ -0,0 +1,397 @@
{
"name": "Acute Bronchitis",
"remarks": [
"This module represents acute bronchitis, a common respiratory infection.",
"Acute bronchitis is usually caused by viruses, less commonly by bacteria.",
"Sources: https://www.cdc.gov/antibiotic-use/bronchitis.html",
"https://www.ncbi.nlm.nih.gov/books/NBK448067/",
"https://www.aafp.org/pubs/afp/issues/2016/1001/p560.html"
],
"states": {
"Initial": {
"type": "Initial",
"direct_transition": "Potential_Onset"
},
"Potential_Onset": {
"type": "Delay",
"range": {
"low": 0,
"high": 80,
"unit": "years"
},
"direct_transition": "Bronchitis_Incidence"
},
"Bronchitis_Incidence": {
"type": "Simple",
"remarks": [
"Acute bronchitis affects approximately 5% of adults annually.",
"Risk is higher in winter months and in those with underlying conditions."
],
"distributed_transition": [
{
"distribution": 0.05,
"transition": "Bronchitis_Onset"
},
{
"distribution": 0.95,
"transition": "No_Bronchitis"
}
]
},
"No_Bronchitis": {
"type": "Delay",
"exact": {
"quantity": 1,
"unit": "years"
},
"direct_transition": "Bronchitis_Incidence"
},
"Bronchitis_Onset": {
"type": "ConditionOnset",
"target_encounter": "Bronchitis_Encounter",
"assign_to_attribute": "bronchitis_condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "10509002",
"display": "Acute bronchitis (disorder)"
},
{
"system": "ICD-10-CM",
"code": "J20.9",
"display": "Acute bronchitis, unspecified"
}
],
"direct_transition": "Bronchitis_Symptom_Cough"
},
"Bronchitis_Symptom_Cough": {
"type": "Symptom",
"symptom": "Cough",
"range": {
"low": 60,
"high": 95
},
"direct_transition": "Bronchitis_Symptom_Sputum"
},
"Bronchitis_Symptom_Sputum": {
"type": "Symptom",
"symptom": "Sputum production",
"range": {
"low": 45,
"high": 85
},
"direct_transition": "Bronchitis_Symptom_Fatigue"
},
"Bronchitis_Symptom_Fatigue": {
"type": "Symptom",
"symptom": "Fatigue",
"range": {
"low": 30,
"high": 70
},
"direct_transition": "Bronchitis_Symptom_Fever"
},
"Bronchitis_Symptom_Fever": {
"type": "Symptom",
"symptom": "Fever",
"range": {
"low": 0,
"high": 40
},
"direct_transition": "Bronchitis_Symptom_Chest_Discomfort"
},
"Bronchitis_Symptom_Chest_Discomfort": {
"type": "Symptom",
"symptom": "Chest discomfort",
"range": {
"low": 20,
"high": 60
},
"direct_transition": "Bronchitis_Symptom_Shortness_Of_Breath"
},
"Bronchitis_Symptom_Shortness_Of_Breath": {
"type": "Symptom",
"symptom": "Shortness of breath",
"range": {
"low": 10,
"high": 50
},
"direct_transition": "Bronchitis_Symptom_Wheezing"
},
"Bronchitis_Symptom_Wheezing": {
"type": "Symptom",
"symptom": "Wheezing",
"range": {
"low": 5,
"high": 40
},
"direct_transition": "Delay_Until_Doctor"
},
"Delay_Until_Doctor": {
"type": "Delay",
"range": {
"low": 2,
"high": 7,
"unit": "days"
},
"direct_transition": "Bronchitis_Encounter"
},
"Bronchitis_Encounter": {
"type": "Encounter",
"encounter_class": "ambulatory",
"reason": "bronchitis_condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "185345009",
"display": "Encounter for symptom (procedure)"
}
],
"direct_transition": "Bronchitis_Diagnosis"
},
"Bronchitis_Diagnosis": {
"type": "Procedure",
"target_encounter": "Bronchitis_Encounter",
"reason": "bronchitis_condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "162673000",
"display": "General examination of patient (procedure)"
}
],
"direct_transition": "Bronchitis_Treatment_Decision"
},
"Bronchitis_Treatment_Decision": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.3,
"transition": "Prescribe_Antibiotics",
"remarks": "Despite guidelines recommending against routine antibiotic use, many patients still receive them"
},
{
"distribution": 0.7,
"transition": "Symptomatic_Treatment"
}
]
},
"Prescribe_Antibiotics": {
"type": "MedicationOrder",
"target_encounter": "Bronchitis_Encounter",
"reason": "bronchitis_condition",
"codes": [
{
"system": "RxNorm",
"code": "1658139",
"display": "Azithromycin 250 MG Oral Tablet"
}
],
"direct_transition": "Symptomatic_Treatment"
},
"Symptomatic_Treatment": {
"type": "MedicationOrder",
"target_encounter": "Bronchitis_Encounter",
"reason": "bronchitis_condition",
"codes": [
{
"system": "RxNorm",
"code": "313782",
"display": "Acetaminophen 325 MG Oral Tablet"
}
],
"direct_transition": "Bronchitis_CarePlan"
},
"Bronchitis_CarePlan": {
"type": "CarePlanStart",
"target_encounter": "Bronchitis_Encounter",
"assign_to_attribute": "bronchitis_careplan",
"reason": "bronchitis_condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "408906008",
"display": "Respiratory therapy (regime/therapy)"
}
],
"activities": [
{
"system": "SNOMED-CT",
"code": "409002008",
"display": "Respiratory therapy (regime/therapy)"
},
{
"system": "SNOMED-CT",
"code": "56251003",
"display": "Supportive care (regime/therapy)"
},
{
"system": "SNOMED-CT",
"code": "11816003",
"display": "Increased fluid intake (regime/therapy)"
}
],
"direct_transition": "End_Encounter"
},
"End_Encounter": {
"type": "EncounterEnd",
"direct_transition": "Recovery_Period"
},
"Recovery_Period": {
"type": "Delay",
"range": {
"low": 10,
"high": 21,
"unit": "days"
},
"direct_transition": "Bronchitis_Resolves"
},
"Bronchitis_Resolves": {
"type": "ConditionEnd",
"referenced_by_attribute": "bronchitis_condition",
"direct_transition": "End_Bronchitis_Symptoms"
},
"End_Bronchitis_Symptoms": {
"type": "Symptom",
"symptom": "Cough",
"exact": {
"quantity": 0
},
"direct_transition": "End_Sputum"
},
"End_Sputum": {
"type": "Symptom",
"symptom": "Sputum production",
"exact": {
"quantity": 0
},
"direct_transition": "End_Fatigue"
},
"End_Fatigue": {
"type": "Symptom",
"symptom": "Fatigue",
"exact": {
"quantity": 0
},
"direct_transition": "End_Fever"
},
"End_Fever": {
"type": "Symptom",
"symptom": "Fever",
"exact": {
"quantity": 0
},
"direct_transition": "End_Chest_Discomfort"
},
"End_Chest_Discomfort": {
"type": "Symptom",
"symptom": "Chest discomfort",
"exact": {
"quantity": 0
},
"direct_transition": "End_Shortness_Of_Breath"
},
"End_Shortness_Of_Breath": {
"type": "Symptom",
"symptom": "Shortness of breath",
"exact": {
"quantity": 0
},
"direct_transition": "End_Wheezing"
},
"End_Wheezing": {
"type": "Symptom",
"symptom": "Wheezing",
"exact": {
"quantity": 0
},
"direct_transition": "End_Medications"
},
"End_Medications": {
"type": "Simple",
"conditional_transition": [
{
"condition": {
"condition_type": "Active Medication",
"codes": [
{
"system": "RxNorm",
"code": "1658139",
"display": "Azithromycin 250 MG Oral Tablet"
}
]
},
"transition": "End_Antibiotics"
},
{
"transition": "End_Pain_Medication"
}
]
},
"End_Antibiotics": {
"type": "MedicationEnd",
"medication_order": {
"codes": [
{
"system": "RxNorm",
"code": "1658139",
"display": "Azithromycin 250 MG Oral Tablet"
}
]
},
"direct_transition": "End_Pain_Medication"
},
"End_Pain_Medication": {
"type": "MedicationEnd",
"medication_order": {
"codes": [
{
"system": "RxNorm",
"code": "313782",
"display": "Acetaminophen 325 MG Oral Tablet"
}
]
},
"direct_transition": "End_CarePlan"
},
"End_CarePlan": {
"type": "CarePlanEnd",
"referenced_by_attribute": "bronchitis_careplan",
"direct_transition": "Potential_Followup"
},
"Potential_Followup": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.1,
"transition": "Followup_Encounter",
"remarks": "Only a small percentage of patients need followup for acute bronchitis"
},
{
"distribution": 0.9,
"transition": "Potential_Onset"
}
]
},
"Followup_Encounter": {
"type": "Encounter",
"encounter_class": "ambulatory",
"codes": [
{
"system": "SNOMED-CT",
"code": "390906007",
"display": "Follow-up encounter (procedure)"
}
],
"direct_transition": "End_Followup"
},
"End_Followup": {
"type": "EncounterEnd",
"direct_transition": "Potential_Onset"
},
"Terminal": {
"type": "Terminal"
}
},
"gmf_version": 2
}

View File

@@ -0,0 +1,879 @@
{
"name": "Acute Myeloid Leukemia for PCOR Research",
"states": {
"Initial": {
"type": "Initial",
"complex_transition": [
{
"condition": {
"condition_type": "Gender",
"gender": "F"
},
"distributions": [
{
"transition": "Cancerous",
"distribution": 0.002
},
{
"transition": "Terminal",
"distribution": 0.998
}
]
},
{
"condition": {
"condition_type": "Gender",
"gender": "M"
},
"distributions": [
{
"transition": "Cancerous",
"distribution": 0.003
},
{
"transition": "Terminal",
"distribution": 0.997
}
]
}
]
},
"Terminal": {
"type": "Terminal"
},
"Levofloxacin": {
"type": "MedicationOrder",
"codes": [
{
"system": "RxNorm",
"code": 199885,
"display": "levofloxacin 500 MG Oral Tablet"
}
],
"chronic": false,
"assign_to_attribute": "levofloxacin",
"administration": true,
"reason": "Acute_Myeloid_Leukemia_AML",
"prescription": {
"dosage": {
"amount": 1,
"frequency": 1,
"period": 1,
"unit": "days"
},
"duration": {
"quantity": 1,
"unit": "days"
}
},
"direct_transition": "Absolute_Neutrophil_Count_ANC"
},
"No_Levofloxacin_Prophylaxis": {
"type": "Simple",
"direct_transition": "Absolute_Neutrophil_Count_ANC2"
},
"Absolute_Neutrophil_Count_ANC": {
"type": "Observation",
"category": "laboratory",
"unit": "10*3/uL",
"codes": [
{
"system": "LOINC",
"code": "751-8",
"display": "Neutrophils [#/volume] in Blood by Automated count"
}
],
"range": {
"low": 250,
"high": 500
},
"direct_transition": "Check_Fever"
},
"Febrile_Neutropenia": {
"type": "ConditionOnset",
"assign_to_attribute": "",
"target_encounter": "Chemotherapy_Inpatient_Encounter",
"codes": [
{
"system": "SNOMED-CT",
"code": "409089005",
"display": "Febrile neutropenia (disorder)"
}
],
"direct_transition": "Check_Bacteremia"
},
"Non-Febrile_Neutropenia": {
"type": "ConditionOnset",
"assign_to_attribute": "",
"target_encounter": "Chemotherapy_Inpatient_Encounter",
"codes": [
{
"system": "SNOMED-CT",
"code": "47318007",
"display": "Drug-induced neutropenia (disorder)"
}
],
"direct_transition": "Transfer_to_Stepdown"
},
"Bacteremia": {
"type": "ConditionOnset",
"assign_to_attribute": "bacteremia",
"target_encounter": "Chemotherapy_Inpatient_Encounter",
"codes": [
{
"system": "SNOMED-CT",
"code": "5758002",
"display": "Bacteremia (finding)"
}
],
"distributed_transition": [
{
"transition": "Transfer_to_ICU",
"distribution": 0.112
},
{
"transition": "Transfer_to_Stepdown",
"distribution": 0.8620000000000001
},
{
"transition": "Death_Event",
"distribution": 0.026
}
]
},
"Check_Bacteremia": {
"type": "Delay",
"distribution": {
"kind": "GAUSSIAN",
"parameters": {
"mean": 90,
"standardDeviation": 30
}
},
"unit": "minutes",
"complex_transition": [
{
"condition": {
"condition_type": "Active Medication",
"codes": [
{
"system": "RxNorm",
"code": 199885,
"display": "levofloxacin 500 MG Oral Tablet"
}
]
},
"distributions": [
{
"transition": "Bacteremia",
"distribution": 0.137
},
{
"transition": "No_Bacteremia",
"distribution": 0.863
}
]
},
{
"condition": {
"condition_type": "Attribute",
"attribute": "levofloxacin",
"operator": "is nil"
},
"distributions": [
{
"transition": "Bacteremia",
"distribution": 0.33
},
{
"transition": "No_Bacteremia",
"distribution": 0.6699999999999999
}
]
}
]
},
"No_Bacteremia": {
"type": "Simple",
"distributed_transition": [
{
"transition": "Transfer_to_ICU",
"distribution": 0.041
},
{
"transition": "Death_Event",
"distribution": 0.015
},
{
"transition": "Transfer_to_Stepdown",
"distribution": 0.944
}
]
},
"Death": {
"type": "Death",
"direct_transition": "End_Encounter2",
"remarks": [
""
],
"codes": [
{
"system": "SNOMED-CT",
"code": "91861009",
"display": "Acute myeloid leukemia (disorder)"
}
]
},
"End_Encounter": {
"type": "EncounterEnd",
"direct_transition": "Terminal",
"discharge_disposition": {
"system": "NUBC",
"code": 1,
"display": "Discharge to Home"
}
},
"Absolute_Neutrophil_Count_ANC2": {
"type": "Observation",
"category": "laboratory",
"unit": "10*3/uL",
"codes": [
{
"system": "LOINC",
"code": "751-8",
"display": "Neutrophils [#/volume] in Blood by Automated count"
}
],
"direct_transition": "Check_Fever2",
"range": {
"low": 250,
"high": 500
}
},
"Normal_Body_Temp": {
"type": "Observation",
"category": "vital-signs",
"unit": "[degF]",
"codes": [
{
"system": "LOINC",
"code": "8310-5",
"display": "Body Temperature"
}
],
"direct_transition": "Non-Febrile_Neutropenia",
"range": {
"low": 96,
"high": 99
}
},
"Fever": {
"type": "Observation",
"category": "vital-signs",
"unit": "[degF]",
"codes": [
{
"system": "LOINC",
"code": "8310-5",
"display": "Body Temperature"
}
],
"range": {
"low": 100.4,
"high": 103
},
"direct_transition": "Febrile_Neutropenia"
},
"Check_Fever": {
"type": "Simple",
"distributed_transition": [
{
"transition": "Fever",
"distribution": 0.656
},
{
"transition": "Normal_Body_Temp",
"distribution": 0.344
}
]
},
"Check_Fever2": {
"type": "Simple",
"distributed_transition": [
{
"transition": "Fever",
"distribution": 0.795
},
{
"transition": "Normal_Body_Temp",
"distribution": 0.20500000000000007
}
]
},
"Chemotherapy": {
"type": "Procedure",
"codes": [
{
"system": "SNOMED-CT",
"code": "367336001",
"display": "Chemotherapy (procedure)"
}
],
"duration": {
"low": 60,
"high": 120,
"unit": "minutes"
},
"reason": "Acute_Myeloid_Leukemia_AML",
"direct_transition": "Determine_Levofloxacin_Prophylaxis"
},
"Transfer_to_ICU": {
"type": "Procedure",
"codes": [
{
"system": "SNOMED-CT",
"code": "305351004",
"display": "Admission to intensive care unit (procedure)"
}
],
"duration": {
"low": 30,
"high": 120,
"unit": "minutes"
},
"complex_transition": [
{
"condition": {
"condition_type": "Active Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "5758002",
"display": "Bacteremia (finding)"
}
]
},
"distributions": [
{
"transition": "Death_Event",
"distribution": 0.167
},
{
"transition": "Transfer_to_Stepdown",
"distribution": 0.833
}
]
},
{
"distributions": [
{
"transition": "Death_Event",
"distribution": 0.061
},
{
"transition": "Transfer_to_Stepdown",
"distribution": 0.9390000000000001
}
]
}
],
"reason": "Febrile_Neutropenia"
},
"Chemotherapy_Inpatient_Encounter": {
"type": "Encounter",
"encounter_class": "inpatient",
"reason": "Acute_Myeloid_Leukemia_AML",
"codes": [
{
"system": "SNOMED-CT",
"code": "185347001",
"display": "Encounter for problem (procedure)"
}
],
"direct_transition": "Wait for Treatment"
},
"Death_Event": {
"type": "Procedure",
"codes": [
{
"system": "SNOMED-CT",
"code": "16983000",
"display": "Death in hospital (event)"
}
],
"duration": {
"low": 30,
"high": 60,
"unit": "minutes"
},
"direct_transition": "Death",
"reason": "Acute_Myeloid_Leukemia_AML"
},
"Determine_Levofloxacin_Prophylaxis": {
"type": "Delay",
"distribution": {
"kind": "GAUSSIAN",
"parameters": {
"mean": 90,
"standardDeviation": 30
}
},
"unit": "minutes",
"lookup_table_transition": [
{
"transition": "Levofloxacin",
"default_probability": 0.2638,
"lookup_table_name": "AML.csv"
},
{
"transition": "No_Levofloxacin_Prophylaxis",
"default_probability": 0.7362,
"lookup_table_name": "AML.csv"
}
]
},
"End_Encounter2": {
"type": "EncounterEnd",
"direct_transition": "Terminal",
"discharge_disposition": {
"system": "NUBC",
"code": 41,
"display": "Expired in medical facility"
}
},
"Transfer_to_Stepdown": {
"type": "Procedure",
"codes": [
{
"system": "SNOMED-CT",
"code": "449214001",
"display": "Transfer to stepdown unit (procedure)"
}
],
"duration": {
"low": 60,
"high": 120,
"unit": "minutes"
},
"direct_transition": "Wait for Discharge",
"reason": "Acute_Myeloid_Leukemia_AML"
},
"Delay_1": {
"type": "Delay",
"distribution": {
"kind": "EXACT",
"parameters": {
"value": 1
}
},
"unit": "years",
"direct_transition": "Acute_Myeloid_Leukemia_AML"
},
"Delay_2": {
"type": "Delay",
"distribution": {
"kind": "EXACT",
"parameters": {
"value": 2
}
},
"unit": "years",
"direct_transition": "Acute_Myeloid_Leukemia_AML"
},
"Delay_3": {
"type": "Delay",
"distribution": {
"kind": "EXACT",
"parameters": {
"value": 3
}
},
"unit": "years",
"direct_transition": "Acute_Myeloid_Leukemia_AML"
},
"Delay_4": {
"type": "Delay",
"distribution": {
"kind": "EXACT",
"parameters": {
"value": 4
}
},
"unit": "years",
"direct_transition": "Acute_Myeloid_Leukemia_AML"
},
"Delay_5": {
"type": "Delay",
"distribution": {
"kind": "EXACT",
"parameters": {
"value": 5
}
},
"unit": "years",
"direct_transition": "Acute_Myeloid_Leukemia_AML"
},
"Delay_6": {
"type": "Delay",
"distribution": {
"kind": "EXACT",
"parameters": {
"value": 6
}
},
"unit": "years",
"direct_transition": "Acute_Myeloid_Leukemia_AML"
},
"Delay_7": {
"type": "Delay",
"distribution": {
"kind": "EXACT",
"parameters": {
"value": 7
}
},
"unit": "years",
"direct_transition": "Acute_Myeloid_Leukemia_AML"
},
"Delay_8": {
"type": "Delay",
"distribution": {
"kind": "EXACT",
"parameters": {
"value": 8
}
},
"unit": "years",
"direct_transition": "Acute_Myeloid_Leukemia_AML"
},
"Delay_9": {
"type": "Delay",
"distribution": {
"kind": "EXACT",
"parameters": {
"value": 9
}
},
"unit": "years",
"direct_transition": "Acute_Myeloid_Leukemia_AML"
},
"Delay_10": {
"type": "Delay",
"distribution": {
"kind": "EXACT",
"parameters": {
"value": 10
}
},
"unit": "years",
"direct_transition": "Acute_Myeloid_Leukemia_AML"
},
"Delay_11": {
"type": "Delay",
"distribution": {
"kind": "EXACT",
"parameters": {
"value": 11
}
},
"unit": "years",
"direct_transition": "Acute_Myeloid_Leukemia_AML"
},
"Delay_12": {
"type": "Delay",
"distribution": {
"kind": "EXACT",
"parameters": {
"value": 12
}
},
"unit": "years",
"direct_transition": "Acute_Myeloid_Leukemia_AML"
},
"Delay_13": {
"type": "Delay",
"distribution": {
"kind": "EXACT",
"parameters": {
"value": 13
}
},
"unit": "years",
"direct_transition": "Acute_Myeloid_Leukemia_AML"
},
"Delay_14": {
"type": "Delay",
"distribution": {
"kind": "EXACT",
"parameters": {
"value": 14
}
},
"unit": "years",
"direct_transition": "Acute_Myeloid_Leukemia_AML"
},
"Delay_15": {
"type": "Delay",
"distribution": {
"kind": "EXACT",
"parameters": {
"value": 15
}
},
"unit": "years",
"direct_transition": "Acute_Myeloid_Leukemia_AML"
},
"Delay_16": {
"type": "Delay",
"distribution": {
"kind": "EXACT",
"parameters": {
"value": 16
}
},
"unit": "years",
"direct_transition": "Acute_Myeloid_Leukemia_AML"
},
"Delay_17": {
"type": "Delay",
"distribution": {
"kind": "EXACT",
"parameters": {
"value": 17
}
},
"unit": "years",
"direct_transition": "Acute_Myeloid_Leukemia_AML"
},
"Delay_18": {
"type": "Delay",
"distribution": {
"kind": "EXACT",
"parameters": {
"value": 18
}
},
"unit": "years",
"direct_transition": "Acute_Myeloid_Leukemia_AML"
},
"Delay_19": {
"type": "Delay",
"distribution": {
"kind": "EXACT",
"parameters": {
"value": 19
}
},
"unit": "years",
"direct_transition": "Acute_Myeloid_Leukemia_AML"
},
"Delay_20": {
"type": "Delay",
"distribution": {
"kind": "EXACT",
"parameters": {
"value": 20
}
},
"unit": "years",
"direct_transition": "Acute_Myeloid_Leukemia_AML"
},
"Delay_21": {
"type": "Delay",
"distribution": {
"kind": "EXACT",
"parameters": {
"value": 21
}
},
"unit": "years",
"direct_transition": "Acute_Myeloid_Leukemia_AML"
},
"Delay_0": {
"type": "Delay",
"distribution": {
"kind": "EXACT",
"parameters": {
"value": 0
}
},
"unit": "years",
"direct_transition": "Acute_Myeloid_Leukemia_AML"
},
"Acute_Myeloid_Leukemia_AML": {
"type": "ConditionOnset",
"assign_to_attribute": "",
"codes": [
{
"system": "SNOMED-CT",
"code": "91861009",
"display": "Acute myeloid leukemia (disorder)"
}
],
"direct_transition": "Chemotherapy_Inpatient_Encounter"
},
"End_Levofloxacin": {
"type": "MedicationEnd",
"direct_transition": "End_AML",
"medication_order": "Levofloxacin",
"codes": [
{
"system": "RxNorm",
"code": 199885,
"display": "levofloxacin 500MG Oral tablet"
}
]
},
"End_Non-Febrile_Neutropenia": {
"type": "ConditionEnd",
"direct_transition": "End_Febrile_Neutropenia",
"condition_onset": "Non-Febrile_Neutropenia"
},
"End_Febrile_Neutropenia": {
"type": "ConditionEnd",
"direct_transition": "End_Bacteremia",
"condition_onset": "Febrile_Neutropenia"
},
"End_Bacteremia": {
"type": "ConditionEnd",
"direct_transition": "End_Encounter",
"condition_onset": "Bacteremia"
},
"End_AML": {
"type": "ConditionEnd",
"direct_transition": "End_Non-Febrile_Neutropenia",
"condition_onset": "Acute_Myeloid_Leukemia_AML"
},
"Cancerous": {
"type": "Simple",
"distributed_transition": [
{
"transition": "Delay_1",
"distribution": 0.098
},
{
"transition": "Delay_2",
"distribution": 0.1264
},
{
"transition": "Delay_3",
"distribution": 0.1094
},
{
"transition": "Delay_4",
"distribution": 0.0645
},
{
"transition": "Delay_5",
"distribution": 0.0533
},
{
"transition": "Delay_6",
"distribution": 0.0345
},
{
"transition": "Delay_7",
"distribution": 0.0362
},
{
"transition": "Delay_8",
"distribution": 0.0318
},
{
"transition": "Delay_9",
"distribution": 0.0354
},
{
"transition": "Delay_10",
"distribution": 0.0346
},
{
"transition": "Delay_11",
"distribution": 0.0289
},
{
"transition": "Delay_12",
"distribution": 0.0312
},
{
"transition": "Delay_13",
"distribution": 0.033
},
{
"transition": "Delay_14",
"distribution": 0.03
},
{
"transition": "Delay_15",
"distribution": 0.0343
},
{
"transition": "Delay_16",
"distribution": 0.0289
},
{
"transition": "Delay_17",
"distribution": 0.0323
},
{
"transition": "Delay_18",
"distribution": 0.0323
},
{
"transition": "Delay_19",
"distribution": 0.0346
},
{
"transition": "Delay_20",
"distribution": 0.0315
},
{
"transition": "Delay_21",
"distribution": 0.0173
},
{
"transition": "Delay_0",
"distribution": 0.04159999999999997
}
]
},
"Wait for Treatment": {
"type": "Delay",
"distribution": {
"kind": "GAUSSIAN",
"parameters": {
"mean": 180,
"standardDeviation": 60
}
},
"unit": "minutes",
"direct_transition": "Chemotherapy"
},
"Wait for Discharge": {
"type": "Delay",
"distribution": {
"kind": "GAUSSIAN",
"parameters": {
"mean": 180,
"standardDeviation": 60
}
},
"unit": "minutes",
"direct_transition": "End_Levofloxacin"
}
},
"remarks": [
"Module Title: Acute Myeloid Leukemia for PCOR Research",
"Version Number: 1.0",
"Date Created: 8/12/2021",
"Module Steward: ONC",
"Module Developer: Clinovations Government + Health",
"Description: This module models Levofloxacin prophylaxis in patients age <=21 years of age. It is based on a microsimulation study to effectively test the utility of Synthea data for PCOR hypothesis testing. This module was designed with a microsimulation-based hypothesis from a study by McCormick et al., which provides an evaluation of the cost effectiveness of levofloxacin use in children with acute myeloid leukemia (AML). The McCormick study includes a decision-analysis model designed to evaluate the cost-effectiveness of levofloxacin prophylaxis compared to no prophylaxis in patients less than or equal to 21 years of age with AML during a single chemotherapy inpatient visit. The study reports outcomes, including the cost of bacterial infection, cost per ICU admission, and cost per death avoided. In order to replicate the costs within this study, costs within appropriate Synthea cost lookup files were updated. In addition, one city in the default demographics file within Synthea was updated with gender, race, and ethnicity parameters from the McCormick study in order to generate similar population characteristics. This module is not intended to include all possible clinical issues related to the patient with acute myeloid leukemia (AML) or represent a clinical care guideline of any kind.",
"",
"Reference: McCormick M, Friehling E, Kalpatthi R, Siripong N, Smith K. Costeffectiveness of levofloxacin prophylaxis against bacterial infection in pediatric patients with acute myeloid leukemia. Pediatric Blood & Cancer. 2020 Oct;67(10):e28469",
"",
"Update January 2023 -- inserted delays and changed population who get AML from everyone to 0.2% of the females and 0.3% of males, according to the American Cancer Society, Cancer Facts & Figures, 2022. https://www.cancer.org/content/dam/cancer-org/research/cancer-facts-and-statistics/annual-cancer-facts-and-figures/2022/2022-cancer-facts-and-figures.pdf",
""
],
"gmf_version": 2
}

View File

@@ -0,0 +1,493 @@
{
"name": "Acute Myocardial Infarction",
"remarks": [
"Acute myocardial infarction (AMI) is commonly known as a heart attack.",
"It occurs when blood flow to a part of the heart is blocked, causing damage to the heart muscle.",
"Risk factors include age, smoking, hypertension, diabetes, obesity, and family history.",
"This module models the onset, diagnosis, treatment, and potential complications of AMI.",
"Information sources:",
"https://www.heart.org/en/health-topics/heart-attack",
"https://www.ncbi.nlm.nih.gov/books/NBK537076/",
"https://www.ahajournals.org/doi/10.1161/CIR.0000000000000617"
],
"states": {
"Initial": {
"type": "Initial",
"remarks": [
"======================================================================",
" INCIDENCE ",
"======================================================================",
"AMI incidence increases with age and is higher in males than females.",
"Approximately 805,000 Americans have a heart attack each year.",
"About 605,000 are first heart attacks and 200,000 are recurrent attacks."
],
"direct_transition": "Age_Guard"
},
"Age_Guard": {
"type": "Guard",
"allow": {
"condition_type": "Age",
"operator": ">=",
"quantity": 35,
"unit": "years"
},
"direct_transition": "AMI_Risk_Assessment"
},
"AMI_Risk_Assessment": {
"type": "Simple",
"complex_transition": [
{
"condition": {
"condition_type": "Gender",
"gender": "M"
},
"distributions": [
{
"distribution": 0.08,
"transition": "AMI_Onset"
},
{
"distribution": 0.92,
"transition": "Terminal"
}
]
},
{
"condition": {
"condition_type": "Gender",
"gender": "F"
},
"distributions": [
{
"distribution": 0.05,
"transition": "AMI_Onset"
},
{
"distribution": 0.95,
"transition": "Terminal"
}
]
}
]
},
"AMI_Onset": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.7,
"transition": "STEMI_Onset"
},
{
"distribution": 0.3,
"transition": "NSTEMI_Onset"
}
]
},
"STEMI_Onset": {
"type": "ConditionOnset",
"target_encounter": "Emergency_Department_Visit",
"assign_to_attribute": "ami",
"codes": [
{
"system": "SNOMED-CT",
"code": "401303003",
"display": "Acute ST segment elevation myocardial infarction (disorder)"
},
{
"system": "ICD-10-CM",
"code": "I21.3",
"display": "ST elevation (STEMI) myocardial infarction of unspecified site"
}
],
"direct_transition": "AMI_Symptoms"
},
"NSTEMI_Onset": {
"type": "ConditionOnset",
"target_encounter": "Emergency_Department_Visit",
"assign_to_attribute": "ami",
"codes": [
{
"system": "SNOMED-CT",
"code": "401314000",
"display": "Acute non-ST segment elevation myocardial infarction (disorder)"
},
{
"system": "ICD-10-CM",
"code": "I21.4",
"display": "Non-ST elevation (NSTEMI) myocardial infarction"
}
],
"direct_transition": "AMI_Symptoms"
},
"AMI_Symptoms": {
"type": "Symptom",
"symptom": "Chest Pain",
"range": {
"low": 80,
"high": 100
},
"direct_transition": "Shortness_of_Breath"
},
"Shortness_of_Breath": {
"type": "Symptom",
"symptom": "Shortness of Breath",
"range": {
"low": 60,
"high": 90
},
"direct_transition": "Nausea"
},
"Nausea": {
"type": "Symptom",
"symptom": "Nausea",
"range": {
"low": 30,
"high": 70
},
"direct_transition": "Diaphoresis"
},
"Diaphoresis": {
"type": "Symptom",
"symptom": "Diaphoresis",
"range": {
"low": 40,
"high": 80
},
"direct_transition": "Arm_Pain"
},
"Arm_Pain": {
"type": "Symptom",
"symptom": "Arm Pain",
"range": {
"low": 30,
"high": 70
},
"direct_transition": "Jaw_Pain"
},
"Jaw_Pain": {
"type": "Symptom",
"symptom": "Jaw Pain",
"range": {
"low": 20,
"high": 60
},
"direct_transition": "Emergency_Department_Visit"
},
"Emergency_Department_Visit": {
"type": "Encounter",
"encounter_class": "emergency",
"reason": "ami",
"codes": [
{
"system": "SNOMED-CT",
"code": "50849002",
"display": "Emergency room admission (procedure)"
}
],
"direct_transition": "Vital_Signs"
},
"Vital_Signs": {
"type": "Procedure",
"reason": "ami",
"codes": [
{
"system": "SNOMED-CT",
"code": "5880005",
"display": "Physical examination procedure (procedure)"
}
],
"direct_transition": "Blood_Pressure"
},
"Blood_Pressure": {
"type": "Observation",
"category": "vital-signs",
"unit": "mm[Hg]",
"codes": [
{
"system": "LOINC",
"code": "8480-6",
"display": "Systolic blood pressure"
}
],
"range": {
"low": 90,
"high": 160
},
"direct_transition": "Heart_Rate"
},
"Heart_Rate": {
"type": "Observation",
"category": "vital-signs",
"unit": "/min",
"codes": [
{
"system": "LOINC",
"code": "8867-4",
"display": "Heart rate"
}
],
"range": {
"low": 80,
"high": 120
},
"direct_transition": "ECG"
},
"ECG": {
"type": "Procedure",
"reason": "ami",
"codes": [
{
"system": "SNOMED-CT",
"code": "29303009",
"display": "Electrocardiographic procedure (procedure)"
}
],
"direct_transition": "Cardiac_Enzymes"
},
"Cardiac_Enzymes": {
"type": "Procedure",
"reason": "ami",
"codes": [
{
"system": "SNOMED-CT",
"code": "313791000",
"display": "Laboratory test (procedure)"
}
],
"direct_transition": "Troponin_Test"
},
"Troponin_Test": {
"type": "Observation",
"category": "laboratory",
"unit": "ng/mL",
"codes": [
{
"system": "LOINC",
"code": "10839-9",
"display": "Troponin I [Mass/volume] in Serum or Plasma"
}
],
"range": {
"low": 0.4,
"high": 10.0
},
"direct_transition": "CK_MB_Test"
},
"CK_MB_Test": {
"type": "Observation",
"category": "laboratory",
"unit": "ng/mL",
"codes": [
{
"system": "LOINC",
"code": "13969-1",
"display": "Creatine kinase.MB [Mass/volume] in Serum or Plasma"
}
],
"range": {
"low": 10.0,
"high": 30.0
},
"direct_transition": "Initial_Treatment"
},
"Initial_Treatment": {
"type": "Simple",
"direct_transition": "Aspirin"
},
"Aspirin": {
"type": "MedicationOrder",
"reason": "ami",
"codes": [
{
"system": "RxNorm",
"code": "1191",
"display": "Aspirin 325 MG Oral Tablet"
}
],
"direct_transition": "Oxygen_Therapy"
},
"Oxygen_Therapy": {
"type": "Procedure",
"reason": "ami",
"codes": [
{
"system": "SNOMED-CT",
"code": "57485005",
"display": "Oxygen therapy (procedure)"
}
],
"direct_transition": "Morphine"
},
"Morphine": {
"type": "MedicationOrder",
"reason": "ami",
"codes": [
{
"system": "RxNorm",
"code": "863671",
"display": "Morphine Sulfate 2 MG/ML Injectable Solution"
}
],
"direct_transition": "Nitroglycerin"
},
"Nitroglycerin": {
"type": "MedicationOrder",
"reason": "ami",
"codes": [
{
"system": "RxNorm",
"code": "705129",
"display": "Nitroglycerin 0.4 MG Sublingual Tablet"
}
],
"direct_transition": "Treatment_Decision"
},
"Treatment_Decision": {
"type": "Simple",
"conditional_transition": [
{
"condition": {
"condition_type": "Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "401303003",
"display": "Acute ST segment elevation myocardial infarction (disorder)"
}
]
},
"transition": "STEMI_Treatment_Decision"
},
{
"transition": "NSTEMI_Treatment"
}
]
},
"STEMI_Treatment_Decision": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.7,
"transition": "Primary_PCI"
},
{
"distribution": 0.3,
"transition": "Thrombolytic_Therapy"
}
]
},
"Primary_PCI": {
"type": "Procedure",
"reason": "ami",
"codes": [
{
"system": "SNOMED-CT",
"code": "415070008",
"display": "Percutaneous coronary intervention (procedure)"
}
],
"duration": {
"low": 60,
"high": 120,
"unit": "minutes"
},
"direct_transition": "Stent_Placement"
},
"Stent_Placement": {
"type": "Procedure",
"reason": "ami",
"codes": [
{
"system": "SNOMED-CT",
"code": "36969009",
"display": "Placement of stent in coronary artery (procedure)"
}
],
"direct_transition": "Post_PCI_Care"
},
"Post_PCI_Care": {
"type": "Procedure",
"reason": "ami",
"codes": [
{
"system": "SNOMED-CT",
"code": "305351004",
"display": "Admission to intensive care unit (procedure)"
}
],
"direct_transition": "Dual_Antiplatelet_Therapy"
},
"Dual_Antiplatelet_Therapy": {
"type": "MedicationOrder",
"reason": "ami",
"codes": [
{
"system": "RxNorm",
"code": "1116632",
"display": "Clopidogrel 75 MG Oral Tablet"
}
],
"direct_transition": "Beta_Blocker"
},
"Thrombolytic_Therapy": {
"type": "Procedure",
"reason": "ami",
"codes": [
{
"system": "SNOMED-CT",
"code": "75540009",
"display": "Thrombolytic therapy (procedure)"
}
],
"direct_transition": "Alteplase"
},
"Alteplase": {
"type": "MedicationOrder",
"reason": "ami",
"codes": [
{
"system": "RxNorm",
"code": "308056",
"display": "Alteplase 50 MG Injection"
}
],
"direct_transition": "Post_Thrombolytic_Care"
},
"Post_Thrombolytic_Care": {
"type": "Procedure",
"reason": "ami",
"codes": [
{
"system": "SNOMED-CT",
"code": "305351004",
"display": "Admission to intensive care unit (procedure)"
}
],
"direct_transition": "Dual_Antiplatelet_Therapy"
},
"NSTEMI_Treatment": {
"type": "Procedure",
"reason": "ami",
"codes": [
{
"system": "SNOMED-CT",
"code": "305351004",
"display": "Admission to intensive care unit (procedure)"
}
],
"direct_transition": "Anticoagulation"
},
"Anticoagulation": {
"type": "MedicationOrder",
"reason": "ami",
"codes": [
{
"system": "RxNorm",
"code": "1361493",
"display": "Heparin Sodium 5000 UNT/ML Injectable Solution"
}
],
"direct_transition": "Dual_Antiplatelet_Therapy"
}
}
}

View File

@@ -0,0 +1,183 @@
{
"name": "Acute pharyngitis",
"remarks": [
"Acute pharyngitis is an inflammation of the pharynx (throat) that typically causes a sore throat and pain with swallowing. It is most commonly caused by viral infections, though bacterial infections (particularly group A Streptococcus) account for 5-15% of cases in adults and 20-30% in children. Acute pharyngitis is highly contagious and spreads through respiratory droplets or direct contact with infected individuals. Most cases resolve within 7-10 days, with or without treatment.",
"Category: Respiratory System",
"Risk factors: - Age: Most common in children aged 5-15 years - Season: More prevalent in winter and early spring - Exposure: Close contact with infected individuals - Environment: Crowded settings (schools, daycare centers, military barracks) - Smoking or exposure to secondhand smoke - Air pollution or irritants - Allergies - Weakened immune system - Chronic fatigue"
],
"states": {
"Initial": {
"type": "Initial",
"direct_transition": "Age_Guard"
},
"Age_Guard": {
"type": "Guard",
"allow": {
"condition_type": "Age",
"operator": ">=",
"quantity": 18,
"unit": "years"
},
"direct_transition": "Delay_Until_Onset"
},
"Delay_Until_Onset": {
"type": "Delay",
"range": {
"low": 0,
"high": 20,
"unit": "years"
},
"direct_transition": "Onset"
},
"Onset": {
"type": "ConditionOnset",
"target_encounter": "Diagnosis_Encounter",
"codes": [
{
"system": "SNOMED-CT",
"code": "64109004",
"display": "Acute pharyngitis"
}
],
"direct_transition": "Diagnosis_Encounter"
},
"Diagnosis_Encounter": {
"type": "Encounter",
"encounter_class": "ambulatory",
"reason": "Onset",
"codes": [
{
"system": "SNOMED-CT",
"code": "185347001",
"display": "Encounter for problem"
}
],
"direct_transition": "End_Diagnosis_Encounter"
},
"End_Diagnosis_Encounter": {
"type": "EncounterEnd",
"direct_transition": "Symptom_0"
},
"Symptom_0": {
"type": "ConditionOnset",
"target_encounter": "Diagnosis_Encounter",
"codes": [
{
"system": "SNOMED-CT",
"code": "418107008",
"display": "Sore throat"
}
],
"direct_transition": "Symptom_1"
},
"Symptom_1": {
"type": "ConditionOnset",
"target_encounter": "Diagnosis_Encounter",
"codes": [
{
"system": "SNOMED-CT",
"code": "418107008",
"display": "Pain when swallowing"
}
],
"direct_transition": "Symptom_2"
},
"Symptom_2": {
"type": "ConditionOnset",
"target_encounter": "Diagnosis_Encounter",
"codes": [
{
"system": "SNOMED-CT",
"code": "418107008",
"display": "Fever (typically higher in bacterial pharyngitis)"
}
],
"direct_transition": "DiagnosticTest_0"
},
"DiagnosticTest_0": {
"type": "Procedure",
"target_encounter": "Diagnosis_Encounter",
"reason": "Onset",
"codes": [
{
"system": "SNOMED-CT",
"code": "386053000",
"display": "Physical examination of throat"
}
],
"direct_transition": "DiagnosticTest_1"
},
"DiagnosticTest_1": {
"type": "Procedure",
"target_encounter": "Diagnosis_Encounter",
"reason": "Onset",
"codes": [
{
"system": "SNOMED-CT",
"code": "386053000",
"display": "Rapid strep test (rapid antigen detection test)"
}
],
"direct_transition": "Prescribe_0"
},
"Prescribe_0": {
"type": "MedicationOrder",
"target_encounter": "Diagnosis_Encounter",
"reason": "Onset",
"codes": [
{
"system": "RxNorm",
"code": "308047",
"display": "Analgesics/antipyretics: acetaminophen"
}
],
"direct_transition": "Prescribe_1"
},
"Prescribe_1": {
"type": "MedicationOrder",
"target_encounter": "Diagnosis_Encounter",
"reason": "Onset",
"codes": [
{
"system": "RxNorm",
"code": "308047",
"display": "ibuprofen"
}
],
"direct_transition": "Prescribe_2"
},
"Prescribe_2": {
"type": "MedicationOrder",
"target_encounter": "Diagnosis_Encounter",
"reason": "Onset",
"codes": [
{
"system": "RxNorm",
"code": "308047",
"display": "Antibiotics"
}
],
"direct_transition": "Follow_Up_Encounter"
},
"Follow_Up_Encounter": {
"type": "Encounter",
"encounter_class": "ambulatory",
"reason": "Onset",
"codes": [
{
"system": "SNOMED-CT",
"code": "390906007",
"display": "Follow-up encounter"
}
],
"direct_transition": "End_Follow_Up_Encounter"
},
"End_Follow_Up_Encounter": {
"type": "EncounterEnd",
"direct_transition": "Terminal"
},
"Terminal": {
"type": "Terminal"
}
}
}

View File

@@ -0,0 +1,84 @@
# Acute Pharyngitis Disease Module Information
## 1. DESCRIPTION
Acute pharyngitis is an inflammation of the pharynx (throat) that typically causes a sore throat and pain with swallowing. It is most commonly caused by viral infections, though bacterial infections (particularly group A Streptococcus) account for 5-15% of cases in adults and 20-30% in children. Acute pharyngitis is highly contagious and spreads through respiratory droplets or direct contact with infected individuals. Most cases resolve within 7-10 days, with or without treatment.
## 2. RISK_FACTORS
- Age: Most common in children aged 5-15 years
- Season: More prevalent in winter and early spring
- Exposure: Close contact with infected individuals
- Environment: Crowded settings (schools, daycare centers, military barracks)
- Smoking or exposure to secondhand smoke
- Air pollution or irritants
- Allergies
- Weakened immune system
- Chronic fatigue
## 3. SYMPTOMS
- Sore throat
- Pain when swallowing
- Fever (typically higher in bacterial pharyngitis)
- Headache
- Fatigue
- Swollen, tender lymph nodes in neck
- Red, inflamed throat and tonsils
- White or yellow patches on tonsils (in streptococcal pharyngitis)
- Hoarseness
- Cough (more common in viral pharyngitis)
- Runny nose (more common in viral pharyngitis)
- Body aches
- Loss of appetite
## 4. DIAGNOSTIC_TESTS
- Physical examination of throat
- Rapid strep test (rapid antigen detection test)
- Throat culture
- Complete blood count (CBC)
- Monospot test (if mononucleosis is suspected)
- Respiratory viral panel (for viral causes)
- C-reactive protein or erythrocyte sedimentation rate (to assess inflammation)
## 5. TREATMENTS
- Medications:
- Analgesics/antipyretics: acetaminophen, ibuprofen (for pain and fever relief)
- Antibiotics (for bacterial pharyngitis only):
- Penicillin V
- Amoxicillin
- Cephalexin (for penicillin-allergic patients)
- Azithromycin (for penicillin-allergic patients)
- Clindamycin (for penicillin-allergic patients)
- Throat lozenges or sprays containing local anesthetics (benzocaine, phenol)
- Corticosteroids (in severe cases): prednisone
- Other interventions:
- Rest
- Increased fluid intake
- Warm salt water gargles
- Humidified air
- Soft, cool foods and avoiding irritating foods
- Honey for symptom relief (not for children under 1 year)
## 6. COMPLICATIONS
- Peritonsillar abscess (quinsy)
- Retropharyngeal abscess
- Sinusitis
- Otitis media (middle ear infection)
- Rheumatic fever (rare complication of untreated strep throat)
- Post-streptococcal glomerulonephritis
- Scarlet fever (with certain strains of strep)
- Dehydration (due to painful swallowing)
- Airway obstruction (in severe cases with significant swelling)
## 7. PROGRESSION
- Initial phase: Begins with throat irritation, progressing to pain within hours to days, often accompanied by fever and malaise
- Peak symptoms: Usually occur 2-3 days after onset, with throat pain, difficulty swallowing, and systemic symptoms
- Resolution: Viral pharyngitis typically resolves within 7-10 days without specific treatment; bacterial pharyngitis improves within 24-48 hours of starting antibiotics
- Outcomes: Most cases resolve completely without sequelae; recurrence is possible with new exposures; some patients may develop chronic or recurrent pharyngitis
## 8. FOLLOW_UP
- Return visit if symptoms worsen or don't improve within expected timeframe
- Complete full course of antibiotics if prescribed (typically 10 days for penicillin)
- Follow-up throat culture may be needed in high-risk patients or recurrent cases
- No routine follow-up needed for uncomplicated cases that resolve
- Evaluation of household contacts may be considered in cases of streptococcal pharyngitis
- Tonsillectomy may be considered for patients with recurrent streptococcal pharyngitis (typically >7 episodes in one year or >5 episodes per year for two consecutive years)

View File

@@ -0,0 +1,183 @@
{
"name": "Acute sinusitis",
"remarks": [
"Acute sinusitis is an inflammation of the paranasal sinuses lasting less than 4 weeks, typically caused by viral or bacterial infections. It often develops after an upper respiratory infection when mucus becomes trapped in the sinuses, creating an environment for pathogens to grow. Symptoms include facial pain, nasal congestion, and purulent nasal discharge. Most cases resolve spontaneously, but some require medical intervention.",
"Category: Respiratory System",
"Risk factors: - Age: All ages affected, but more common in adults 18-45 years - Gender: Slightly more common in women - Anatomical factors: Nasal polyps, deviated septum, nasal bone spurs - Environmental: Allergies, cigarette smoke exposure, air pollution - Medical conditions: Recent upper respiratory infections, dental infections, immunodeficiency - Seasonal: More common during cold and flu season (fall and winter)"
],
"states": {
"Initial": {
"type": "Initial",
"direct_transition": "Age_Guard"
},
"Age_Guard": {
"type": "Guard",
"allow": {
"condition_type": "Age",
"operator": ">=",
"quantity": 18,
"unit": "years"
},
"direct_transition": "Delay_Until_Onset"
},
"Delay_Until_Onset": {
"type": "Delay",
"range": {
"low": 0,
"high": 20,
"unit": "years"
},
"direct_transition": "Onset"
},
"Onset": {
"type": "ConditionOnset",
"target_encounter": "Diagnosis_Encounter",
"codes": [
{
"system": "SNOMED-CT",
"code": "64109004",
"display": "Acute sinusitis"
}
],
"direct_transition": "Diagnosis_Encounter"
},
"Diagnosis_Encounter": {
"type": "Encounter",
"encounter_class": "ambulatory",
"reason": "Onset",
"codes": [
{
"system": "SNOMED-CT",
"code": "185347001",
"display": "Encounter for problem"
}
],
"direct_transition": "End_Diagnosis_Encounter"
},
"End_Diagnosis_Encounter": {
"type": "EncounterEnd",
"direct_transition": "Symptom_0"
},
"Symptom_0": {
"type": "ConditionOnset",
"target_encounter": "Diagnosis_Encounter",
"codes": [
{
"system": "SNOMED-CT",
"code": "418107008",
"display": "Facial pain/pressure (particularly over affected sinuses)"
}
],
"direct_transition": "Symptom_1"
},
"Symptom_1": {
"type": "ConditionOnset",
"target_encounter": "Diagnosis_Encounter",
"codes": [
{
"system": "SNOMED-CT",
"code": "418107008",
"display": "Nasal congestion"
}
],
"direct_transition": "Symptom_2"
},
"Symptom_2": {
"type": "ConditionOnset",
"target_encounter": "Diagnosis_Encounter",
"codes": [
{
"system": "SNOMED-CT",
"code": "418107008",
"display": "Purulent nasal discharge"
}
],
"direct_transition": "DiagnosticTest_0"
},
"DiagnosticTest_0": {
"type": "Procedure",
"target_encounter": "Diagnosis_Encounter",
"reason": "Onset",
"codes": [
{
"system": "SNOMED-CT",
"code": "386053000",
"display": "Physical examination (including nasal endoscopy)"
}
],
"direct_transition": "DiagnosticTest_1"
},
"DiagnosticTest_1": {
"type": "Procedure",
"target_encounter": "Diagnosis_Encounter",
"reason": "Onset",
"codes": [
{
"system": "SNOMED-CT",
"code": "386053000",
"display": "Nasal swab culture (in persistent cases)"
}
],
"direct_transition": "Prescribe_0"
},
"Prescribe_0": {
"type": "MedicationOrder",
"target_encounter": "Diagnosis_Encounter",
"reason": "Onset",
"codes": [
{
"system": "RxNorm",
"code": "308047",
"display": "Analgesics: acetaminophen"
}
],
"direct_transition": "Prescribe_1"
},
"Prescribe_1": {
"type": "MedicationOrder",
"target_encounter": "Diagnosis_Encounter",
"reason": "Onset",
"codes": [
{
"system": "RxNorm",
"code": "308047",
"display": "ibuprofen"
}
],
"direct_transition": "Prescribe_2"
},
"Prescribe_2": {
"type": "MedicationOrder",
"target_encounter": "Diagnosis_Encounter",
"reason": "Onset",
"codes": [
{
"system": "RxNorm",
"code": "308047",
"display": "Intranasal corticosteroids: fluticasone"
}
],
"direct_transition": "Follow_Up_Encounter"
},
"Follow_Up_Encounter": {
"type": "Encounter",
"encounter_class": "ambulatory",
"reason": "Onset",
"codes": [
{
"system": "SNOMED-CT",
"code": "390906007",
"display": "Follow-up encounter"
}
],
"direct_transition": "End_Follow_Up_Encounter"
},
"End_Follow_Up_Encounter": {
"type": "EncounterEnd",
"direct_transition": "Terminal"
},
"Terminal": {
"type": "Terminal"
}
}
}

View File

@@ -0,0 +1,81 @@
# Acute Sinusitis Disease Module Information
## 1. DESCRIPTION
Acute sinusitis is an inflammation of the paranasal sinuses lasting less than 4 weeks, typically caused by viral or bacterial infections. It often develops after an upper respiratory infection when mucus becomes trapped in the sinuses, creating an environment for pathogens to grow. Symptoms include facial pain, nasal congestion, and purulent nasal discharge. Most cases resolve spontaneously, but some require medical intervention.
## 2. RISK_FACTORS
- Age: All ages affected, but more common in adults 18-45 years
- Gender: Slightly more common in women
- Anatomical factors: Nasal polyps, deviated septum, nasal bone spurs
- Environmental: Allergies, cigarette smoke exposure, air pollution
- Medical conditions: Recent upper respiratory infections, dental infections, immunodeficiency
- Seasonal: More common during cold and flu season (fall and winter)
## 3. SYMPTOMS
- Facial pain/pressure (particularly over affected sinuses)
- Nasal congestion
- Purulent nasal discharge
- Decreased sense of smell
- Fever (more common in bacterial sinusitis)
- Headache
- Fatigue
- Cough (often worse at night)
- Ear pressure
- Halitosis (bad breath)
## 4. DIAGNOSTIC_TESTS
- Physical examination (including nasal endoscopy)
- Nasal swab culture (in persistent cases)
- Imaging studies (for complicated cases):
- CT scan of sinuses
- X-ray of sinuses
- Allergy testing (if allergic sinusitis suspected)
- Transillumination of sinuses
## 5. TREATMENTS
- Medications:
- Analgesics: acetaminophen, ibuprofen (for pain relief)
- Intranasal corticosteroids: fluticasone, mometasone (reduce inflammation)
- Antibiotics: amoxicillin, amoxicillin-clavulanate, doxycycline (for bacterial sinusitis)
- Decongestants: pseudoephedrine (short-term relief of congestion)
- Antihistamines: loratadine, cetirizine (if allergic component)
- Saline nasal sprays (moisturize nasal passages)
- Procedures:
- Nasal irrigation with saline solution
- Sinus drainage (in severe cases)
- Other interventions:
- Increased fluid intake
- Warm compresses to face
- Humidification of air
- Elevation of head while sleeping
## 6. COMPLICATIONS
- Chronic sinusitis (lasting >12 weeks)
- Orbital cellulitis (infection of eye socket)
- Osteomyelitis (bone infection)
- Meningitis
- Brain abscess
- Cavernous sinus thrombosis
- Mucocele formation
- Spread of infection to nearby structures
## 7. PROGRESSION
- Starts: Usually begins after a viral upper respiratory infection (common cold), with initial symptoms of nasal congestion and discharge
- Development: If drainage is blocked, bacteria may grow in the sinuses, leading to bacterial sinusitis with worsening pain, pressure, and purulent discharge
- Outcomes:
- Most viral cases (>70%) resolve spontaneously within 7-10 days
- Bacterial cases typically improve with antibiotics within 10-14 days
- Some cases may progress to chronic sinusitis
- Rare cases develop serious complications requiring urgent intervention
## 8. FOLLOW_UP
- Return visit if symptoms worsen or fail to improve after 7-10 days
- Follow-up visit after completing antibiotic course for bacterial sinusitis
- Referral to otolaryngologist (ENT) if:
- Symptoms persist despite treatment
- Recurrent episodes (>3-4 per year)
- Anatomical abnormalities suspected
- Complications develop
- Allergy evaluation if allergic triggers suspected

View File

@@ -0,0 +1,417 @@
{
"name": "All anxiety disorders",
"remarks": [
"This module models the prevalence and progression of anxiety disorders based on epidemiological data",
"Anxiety disorders are the most common mental disorders in the US, affecting approximately 19.1% of adults annually",
"Women are more likely than men to experience anxiety disorders (23.4% vs 14.3%)",
"Sources: https://www.nimh.nih.gov/health/statistics/any-anxiety-disorder and https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5573566/"
],
"states": {
"Initial": {
"type": "Initial",
"conditional_transition": [
{
"transition": "Female",
"condition": {
"condition_type": "Gender",
"gender": "F"
}
},
{
"transition": "Male",
"condition": {
"condition_type": "Gender",
"gender": "M"
}
},
{
"transition": "Terminal"
}
]
},
"Terminal": {
"type": "Terminal"
},
"Female": {
"type": "Simple",
"remarks": [
"Women have higher prevalence of anxiety disorders at 23.4%",
"Source: https://www.nimh.nih.gov/health/statistics/any-anxiety-disorder"
],
"distributed_transition": [
{
"transition": "Female_Anxiety_Onset",
"distribution": 0.234
},
{
"transition": "Terminal",
"distribution": 0.766
}
]
},
"Male": {
"type": "Simple",
"remarks": [
"Men have lower prevalence of anxiety disorders at 14.3%",
"Source: https://www.nimh.nih.gov/health/statistics/any-anxiety-disorder"
],
"distributed_transition": [
{
"transition": "Male_Anxiety_Onset",
"distribution": 0.143
},
{
"transition": "Terminal",
"distribution": 0.857
}
]
},
"Female_Anxiety_Onset": {
"type": "Simple",
"distributed_transition": [
{
"transition": "Childhood_Onset",
"distribution": 0.31
},
{
"transition": "Adolescent_Onset",
"distribution": 0.47
},
{
"transition": "Adult_Onset",
"distribution": 0.22
}
],
"remarks": [
"Age of onset distribution based on epidemiological studies",
"Source: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3018839/"
]
},
"Male_Anxiety_Onset": {
"type": "Simple",
"distributed_transition": [
{
"transition": "Childhood_Onset",
"distribution": 0.38
},
{
"transition": "Adolescent_Onset",
"distribution": 0.43
},
{
"transition": "Adult_Onset",
"distribution": 0.19
}
],
"remarks": [
"Age of onset distribution based on epidemiological studies",
"Source: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3018839/"
]
},
"Childhood_Onset": {
"type": "Delay",
"range": {
"low": 5,
"high": 11,
"unit": "years"
},
"direct_transition": "Anxiety_Disorder_Onset"
},
"Adolescent_Onset": {
"type": "Delay",
"range": {
"low": 12,
"high": 19,
"unit": "years"
},
"direct_transition": "Anxiety_Disorder_Onset"
},
"Adult_Onset": {
"type": "Delay",
"range": {
"low": 20,
"high": 50,
"unit": "years"
},
"direct_transition": "Anxiety_Disorder_Onset"
},
"Anxiety_Disorder_Onset": {
"type": "ConditionOnset",
"target_encounter": "Anxiety_Diagnosis_Encounter",
"codes": [
{
"system": "ICD-10-CM",
"code": "F41.9",
"display": "Anxiety disorder, unspecified"
},
{
"system": "SNOMED-CT",
"code": "197480006",
"display": "Anxiety disorder"
}
],
"direct_transition": "Symptom_Worry"
},
"Symptom_Worry": {
"type": "Symptom",
"symptom": "Excessive worry",
"range": {
"low": 50,
"high": 100
},
"direct_transition": "Symptom_Restlessness"
},
"Symptom_Restlessness": {
"type": "Symptom",
"symptom": "Restlessness",
"range": {
"low": 40,
"high": 90
},
"direct_transition": "Symptom_Fatigue"
},
"Symptom_Fatigue": {
"type": "Symptom",
"symptom": "Fatigue",
"range": {
"low": 30,
"high": 80
},
"direct_transition": "Symptom_Concentration"
},
"Symptom_Concentration": {
"type": "Symptom",
"symptom": "Difficulty concentrating",
"range": {
"low": 30,
"high": 70
},
"direct_transition": "Symptom_Irritability"
},
"Symptom_Irritability": {
"type": "Symptom",
"symptom": "Irritability",
"range": {
"low": 40,
"high": 90
},
"direct_transition": "Symptom_Tension"
},
"Symptom_Tension": {
"type": "Symptom",
"symptom": "Muscle tension",
"range": {
"low": 30,
"high": 80
},
"direct_transition": "Symptom_Sleep"
},
"Symptom_Sleep": {
"type": "Symptom",
"symptom": "Sleep disturbance",
"range": {
"low": 40,
"high": 90
},
"direct_transition": "Delay_Until_Diagnosis"
},
"Delay_Until_Diagnosis": {
"type": "Delay",
"range": {
"low": 3,
"high": 24,
"unit": "months"
},
"direct_transition": "Anxiety_Diagnosis_Encounter"
},
"Anxiety_Diagnosis_Encounter": {
"type": "Encounter",
"encounter_class": "ambulatory",
"codes": [
{
"system": "SNOMED-CT",
"code": "185347001",
"display": "Encounter for problem"
}
],
"direct_transition": "Anxiety_Diagnosis"
},
"Anxiety_Diagnosis": {
"type": "ConditionOnset",
"assign_to_attribute": "anxiety_disorder",
"codes": [
{
"system": "ICD-10-CM",
"code": "F5_ALLANXIOUS",
"display": "All anxiety disorders"
},
{
"system": "SNOMED-CT",
"code": "197480006",
"display": "Anxiety disorder"
}
],
"direct_transition": "Anxiety_CarePlan"
},
"Anxiety_CarePlan": {
"type": "CarePlanStart",
"codes": [
{
"system": "SNOMED-CT",
"code": "304561007",
"display": "Anxiety management plan"
}
],
"activities": [
{
"system": "SNOMED-CT",
"code": "183401009",
"display": "Stress management"
},
{
"system": "SNOMED-CT",
"code": "304481008",
"display": "Psychotherapy"
}
],
"direct_transition": "Treatment_Decision"
},
"Treatment_Decision": {
"type": "Simple",
"distributed_transition": [
{
"transition": "Medication_SSRI",
"distribution": 0.5
},
{
"transition": "Medication_SNRI",
"distribution": 0.2
},
{
"transition": "Medication_Benzodiazepine",
"distribution": 0.15
},
{
"transition": "Psychotherapy_Only",
"distribution": 0.15
}
]
},
"Medication_SSRI": {
"type": "MedicationOrder",
"codes": [
{
"system": "RxNorm",
"code": "312940",
"display": "Sertraline 50 MG Oral Tablet"
}
],
"direct_transition": "Anxiety_Followup"
},
"Medication_SNRI": {
"type": "MedicationOrder",
"codes": [
{
"system": "RxNorm",
"code": "849727",
"display": "Venlafaxine 75 MG Oral Tablet"
}
],
"direct_transition": "Anxiety_Followup"
},
"Medication_Benzodiazepine": {
"type": "MedicationOrder",
"codes": [
{
"system": "RxNorm",
"code": "197319",
"display": "Lorazepam 0.5 MG Oral Tablet"
}
],
"direct_transition": "Anxiety_Followup"
},
"Psychotherapy_Only": {
"type": "Procedure",
"codes": [
{
"system": "SNOMED-CT",
"code": "304891004",
"display": "Cognitive behavioral therapy"
}
],
"direct_transition": "Anxiety_Followup"
},
"Anxiety_Followup": {
"type": "Encounter",
"encounter_class": "ambulatory",
"codes": [
{
"system": "SNOMED-CT",
"code": "390906007",
"display": "Follow-up encounter"
}
],
"direct_transition": "Anxiety_Progression"
},
"Anxiety_Progression": {
"type": "Simple",
"distributed_transition": [
{
"transition": "Anxiety_Remission",
"distribution": 0.4
},
{
"transition": "Anxiety_Chronic",
"distribution": 0.6
}
],
"remarks": [
"About 40% of anxiety patients achieve remission within 1 year of treatment",
"Source: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5573566/"
]
},
"Anxiety_Remission": {
"type": "ConditionEnd",
"referenced_by_attribute": "anxiety_disorder",
"direct_transition": "End_Anxiety_CarePlan"
},
"Anxiety_Chronic": {
"type": "Delay",
"range": {
"low": 2,
"high": 10,
"unit": "years"
},
"direct_transition": "Anxiety_Recurrence_Chance"
},
"Anxiety_Recurrence_Chance": {
"type": "Simple",
"distributed_transition": [
{
"transition": "Anxiety_Remission",
"distribution": 0.3
},
{
"transition": "Anxiety_Chronic",
"distribution": 0.7
}
],
"remarks": [
"Chronic anxiety often follows a relapsing-remitting course",
"Source: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5573566/"
]
},
"End_Anxiety_CarePlan": {
"type": "CarePlanEnd",
"codes": [
{
"system": "SNOMED-CT",
"code": "304561007",
"display": "Anxiety management plan"
}
],
"direct_transition": "Terminal"
}
},
"gmf_version": 2
}

View File

@@ -0,0 +1,366 @@
{
"name": "Allergic Rhinitis",
"remarks": [
"Better known as 'hay fever' or 'seasonal allergies'.",
"Statistics are from the American College of Allergy, Asthma, & Immunology (ACAAI):",
"http://acaai.org/news/facts-statistics/allergies",
"or the Allergy and Asthma Foundation of America (AAFA):",
"http://www.aafa.org/page/allergy-facts.aspx"
],
"states": {
"Initial": {
"type": "Initial",
"direct_transition": "Delay_For_Atopy"
},
"Delay_For_Atopy": {
"type": "Delay",
"remarks": [
"The Atopy module must be processed before any of the allergy modules so ",
"atopy can appropriately influence allergies. Delaying the smallest possible ",
"time step to ensure this happens."
],
"exact": {
"quantity": 1,
"unit": "weeks"
},
"conditional_transition": [
{
"condition": {
"condition_type": "Attribute",
"attribute": "atopic",
"operator": "is not nil"
},
"transition": "Atopic"
},
{
"transition": "Not_Atopic"
}
]
},
"Atopic": {
"type": "Simple",
"remarks": [
"85% of all atopic patients develop allergic rhinitis. See the Atopy model for more info."
],
"distributed_transition": [
{
"distribution": 0.85,
"transition": "Delay_Until_Early_Mid_Childhood"
},
{
"distribution": 0.15,
"transition": "Terminal"
}
]
},
"Not_Atopic": {
"type": "Simple",
"remarks": [
"Estimated 50 million Americans affected by nasal allergies (ACAAI). 50M / 318.9M => 15.7%.",
"It makes more sense to wait until early-mid childhood (2-6 years old) for these ",
"symptoms to appear and to be diagnosed by a doctor."
],
"distributed_transition": [
{
"distribution": 0.029,
"transition": "Delay_Until_Early_Mid_Childhood"
},
{
"distribution": 0.971,
"transition": "Terminal"
}
]
},
"Delay_Until_Early_Mid_Childhood": {
"type": "Delay",
"range": {
"low": 2,
"high": 6,
"unit": "years"
},
"direct_transition": "Has_Allergic_Rhinitis"
},
"Has_Allergic_Rhinitis": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.2,
"transition": "Has_Seasonal_Allergic_Rhinitis",
"remarks": [
"Seasonal allergies occur only at a specific time of year. They can be more actue but ",
"are easily treated. 20% of Americans have just seasonal allergies.",
"source: http://www.neilmed.com/neilmedblog/2014/08/seasonal-and-perennial-allergic-rhinitis/"
]
},
{
"distribution": 0.4,
"transition": "Has_Perennial_Allergic_Rhinitis",
"remarks": [
"Perennial allergies are not influenced by the seasons. They are typically tied to other ",
"allergens like pet dander, mold, and dust mites."
]
},
{
"distribution": 0.4,
"transition": "Has_Perennial_And_Seasonal_Allergic_Rhinitis",
"remarks": [
"Perennial allergies flare up in the spring with additional allergies, like grass and ",
"tree pollens."
]
}
]
},
"Has_Seasonal_Allergic_Rhinitis": {
"type": "ConditionOnset",
"assign_to_attribute": "allergic_rhinitis",
"target_encounter": "Allergic_Rhinitis_Diagnosis",
"codes": [
{
"system": "SNOMED-CT",
"code": "367498001",
"display": "Seasonal allergic rhinitis (disorder)"
}
],
"direct_transition": "Allergic_Rhinitis_Symptom1"
},
"Has_Perennial_Allergic_Rhinitis": {
"type": "ConditionOnset",
"assign_to_attribute": "allergic_rhinitis",
"target_encounter": "Allergic_Rhinitis_Diagnosis",
"codes": [
{
"system": "SNOMED-CT",
"code": "446096008",
"display": "Perennial allergic rhinitis (disorder)"
}
],
"direct_transition": "Allergic_Rhinitis_Symptom1"
},
"Has_Perennial_And_Seasonal_Allergic_Rhinitis": {
"type": "ConditionOnset",
"assign_to_attribute": "allergic_rhinitis",
"target_encounter": "Allergic_Rhinitis_Diagnosis",
"codes": [
{
"system": "SNOMED-CT",
"code": "232353008",
"display": "Perennial allergic rhinitis with seasonal variation (disorder)"
}
],
"direct_transition": "Allergic_Rhinitis_Symptom1"
},
"Allergic_Rhinitis_Diagnosis": {
"type": "Encounter",
"encounter_class": "ambulatory",
"reason": "allergic_rhinitis",
"telemedicine_possibility": "possible",
"codes": [
{
"system": "SNOMED-CT",
"code": "185345009",
"display": "Encounter for symptom (procedure)"
}
],
"direct_transition": "Prescribe_OTC_Antihistamine"
},
"Allergic_Rhinitis_Symptom1": {
"type": "Symptom",
"symptom": "Nasal Congestion",
"range": {
"low": 0,
"high": 25
},
"direct_transition": "Allergic_Rhinitis_Symptom2"
},
"Allergic_Rhinitis_Symptom2": {
"type": "Symptom",
"symptom": "Nasal Discharge",
"range": {
"low": 0,
"high": 25
},
"direct_transition": "Allergic_Rhinitis_Symptom3"
},
"Allergic_Rhinitis_Symptom3": {
"type": "Symptom",
"symptom": "Itching",
"range": {
"low": 0,
"high": 25
},
"direct_transition": "Allergic_Rhinitis_Symptom4"
},
"Allergic_Rhinitis_Symptom4": {
"type": "Symptom",
"symptom": "Sneezing Fits",
"range": {
"low": 0,
"high": 25
},
"direct_transition": "Allergic_Rhinitis_Symptom5"
},
"Allergic_Rhinitis_Symptom5": {
"type": "Symptom",
"symptom": "Ear Pressure",
"range": {
"low": 0,
"high": 25
},
"direct_transition": "Symptom_Period"
},
"Symptom_Period": {
"type": "Delay",
"range": {
"low": 2,
"high": 3,
"unit": "weeks"
},
"direct_transition": "Allergic_Rhinitis_Diagnosis"
},
"Prescribe_OTC_Antihistamine": {
"type": "CallSubmodule",
"remarks": [
"This submodule will only prescribe an antihistamine if one is ",
"not already prescribed."
],
"submodule": "medications/otc_antihistamine",
"direct_transition": "Advise_To_Visit_Allergist"
},
"Advise_To_Visit_Allergist": {
"type": "SetAttribute",
"attribute": "visit_allergist",
"value": true,
"direct_transition": "End_Allergic_Rhinitis_Diagnosis"
},
"End_Allergic_Rhinitis_Diagnosis": {
"type": "EncounterEnd",
"direct_transition": "Living_With_Allergic_Rhinitis"
},
"Living_With_Allergic_Rhinitis": {
"type": "Guard",
"allow": {
"condition_type": "Age",
"operator": ">",
"quantity": 18,
"unit": "years"
},
"direct_transition": "Outgrow_Allergic_Rhinitis?"
},
"Outgrow_Allergic_Rhinitis?": {
"type": "Guard",
"remarks": [
"It's very uncommon for a person to 'outgrow' allergic rhinitis, ",
"but symptoms can lessen or disappear as a child ages or if they ",
"are given immunotherapy (85%)."
],
"allow": {
"condition_type": "Not",
"condition": {
"condition_type": "Or",
"conditions": [
{
"condition_type": "Active Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "419263009",
"display": "Allergy to tree pollen (finding)"
}
]
},
{
"condition_type": "Active Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "418689008",
"display": "Allergy to grass pollen (finding)"
}
]
},
{
"condition_type": "Active Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "717234006",
"display": "Allergy to animal protein (finding)"
}
]
},
{
"condition_type": "Active Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "232350006",
"display": "Allergy to dust mite protein (finding)"
}
]
},
{
"condition_type": "Active Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "419474003",
"display": "Allergy to mold (finding)"
}
]
}
]
}
},
"direct_transition": "Allergic_Rhinitis_Subsides"
},
"Allergic_Rhinitis_Subsides": {
"type": "ConditionEnd",
"referenced_by_attribute": "allergic_rhinitis",
"direct_transition": "Allergic_Rhinitis_Symptom1_Ends"
},
"Allergic_Rhinitis_Symptom1_Ends": {
"type": "Symptom",
"symptom": "Nasal Congestion",
"exact": {
"quantity": 0
},
"direct_transition": "Allergic_Rhinitis_Symptom2_Ends"
},
"Allergic_Rhinitis_Symptom2_Ends": {
"type": "Symptom",
"symptom": "Nasal Discharge",
"exact": {
"quantity": 0
},
"direct_transition": "Allergic_Rhinitis_Symptom3_Ends"
},
"Allergic_Rhinitis_Symptom3_Ends": {
"type": "Symptom",
"symptom": "Itching",
"exact": {
"quantity": 0
},
"direct_transition": "Allergic_Rhinitis_Symptom4_Ends"
},
"Allergic_Rhinitis_Symptom4_Ends": {
"type": "Symptom",
"symptom": "Sneezing Fits",
"exact": {
"quantity": 0
},
"direct_transition": "Allergic_Rhinitis_Symptom5_Ends"
},
"Allergic_Rhinitis_Symptom5_Ends": {
"type": "Symptom",
"symptom": "Ear Pressure",
"exact": {
"quantity": 0
},
"direct_transition": "Terminal"
},
"Terminal": {
"type": "Terminal"
}
},
"gmf_version": 1
}

View File

@@ -0,0 +1,274 @@
{
"name": "Allergies and Treatment",
"remarks": [
"This module onsets allergies and manages the treatment of allergies and ",
"allergic diseases. After the initial series of AllergyOnset states, the ",
"module waits for an allergic condition (as a result of a person's allergies)",
"to prompt treatment.",
"Primary reference for allergy statistics: ",
"https://web.archive.org/web/20100407195412/http://www.niaid.nih.gov/topics/foodAllergy/understanding/Pages/quickFacts.aspx"
],
"states": {
"Initial": {
"type": "Initial",
"direct_transition": "Delay_For_Atopy"
},
"Delay_For_Atopy": {
"type": "Delay",
"remarks": [
"The Atopy module must be processed before any of the allergy modules so ",
"atopy can appropriately influence allergies. Delaying the smallest possible ",
"time step to ensure this happens."
],
"exact": {
"quantity": 1,
"unit": "weeks"
},
"direct_transition": "Food_Allergy_Incidence_Submodule"
},
"Food_Allergy_Incidence_Submodule": {
"type": "CallSubmodule",
"remarks": [
"This submodule onsets the various food allergies that ",
"a person can get, with different incidences for atopic and non-atopic ",
"patients."
],
"submodule": "allergies/food_allergy_incidence",
"direct_transition": "Drug_Allergy_Incidence_Submodule"
},
"Drug_Allergy_Incidence_Submodule": {
"type": "CallSubmodule",
"remarks": [
"This submodule onsets the various drug allergies that a person can get."
],
"submodule": "allergies/drug_allergy_incidence",
"direct_transition": "Environmental_Allergy_Incidence_Submodule"
},
"Environmental_Allergy_Incidence_Submodule": {
"type": "CallSubmodule",
"remarks": [
"This submodule onsets the various environmental allergies that ",
"a person can get, with different incidences for atopic and non-atopic ",
"patients."
],
"submodule": "allergies/environmental_allergy_incidence",
"direct_transition": "Allergist_Guard"
},
"Allergist_Guard": {
"type": "Guard",
"remarks": [
"======================================================================",
" ALLERGY TREATMENT/CARE ",
"======================================================================",
"Now that the patient is suspected to have an allergy, we refer them to ",
"an allergist for specialized treatment.",
"The following can prompt a visit to the allergist: ",
"- Asthma attack ",
"- Moderate to severe eczema ",
"- Any allergic reaction to food ",
"- Moderate to severe allergic rhinitis symptoms ",
"The asthma, eczema, and allergic rhinitis submodules set the 'visit_allergist' ",
"attribute to trigger the visit. At the first visit to an allergist an ",
"allergy panel is always performed."
],
"allow": {
"condition_type": "Attribute",
"attribute": "visit_allergist",
"operator": "is not nil"
},
"direct_transition": "Allergy_Unspecified"
},
"Delay_For_Allergist_Initial_Visit": {
"type": "Delay",
"remarks": [
"Other modules are not expected to make this delay after making a ",
"'visit_allergist' recommendation."
],
"range": {
"low": 1,
"high": 7,
"unit": "days"
},
"direct_transition": "Allergist_Initial_Visit"
},
"Allergist_Initial_Visit": {
"type": "Encounter",
"remarks": [
"This is the big one! Whatever allergies a patient has will be formally ",
"diagnosed at this encounter."
],
"encounter_class": "ambulatory",
"codes": [
{
"system": "SNOMED-CT",
"code": "185347001",
"display": "Encounter for problem (procedure)"
}
],
"conditional_transition": [
{
"condition": {
"condition_type": "Date",
"operator": ">",
"year": 1974
},
"transition": "Administer_Allergy_Test"
},
{
"transition": "General_Allergy_CarePlan"
}
],
"reason": "Allergy_Unspecified"
},
"Administer_Allergy_Test": {
"type": "Procedure",
"duration": {
"low": 20,
"high": 40,
"unit": "minutes"
},
"codes": [
{
"system": "SNOMED-CT",
"code": "395142003",
"display": "Allergy screening test (procedure)"
}
],
"direct_transition": "Allergy_Panel"
},
"Allergy_Panel": {
"type": "CallSubmodule",
"submodule": "allergies/allergy_panel",
"direct_transition": "Prescribe_OTC_Antihistamine"
},
"Prescribe_OTC_Antihistamine": {
"type": "CallSubmodule",
"remarks": [
"This submodule will only prescribe an antihistamine if one is ",
"not already prescribed."
],
"submodule": "medications/otc_antihistamine",
"direct_transition": "General_Allergy_CarePlan"
},
"General_Allergy_CarePlan": {
"type": "CarePlanStart",
"remarks": [
"Allergy maintenance is all about self care."
],
"codes": [
{
"system": "SNOMED-CT",
"code": "384758001",
"display": "Self-care interventions (procedure)"
}
],
"activities": [
{
"system": "SNOMED-CT",
"code": "58332002",
"display": "Allergy education (procedure)"
}
],
"conditional_transition": [
{
"condition": {
"condition_type": "Date",
"operator": ">=",
"year": 1987
},
"transition": "Prescribe_Epipen"
},
{
"transition": "End_Allergist_Initial_Visit"
}
]
},
"Prescribe_Epipen": {
"type": "MedicationOrder",
"remarks": [
"FDA approved in 1987. It's highly likely that this prescription ",
"will never end - it will just be periodically renewed during the ",
"patient's lifetime."
],
"codes": [
{
"system": "RxNorm",
"code": "1870230",
"display": "NDA020800 0.3 ML Epinephrine 1 MG/ML Auto-Injector"
}
],
"prescription": {
"as_needed": true
},
"direct_transition": "End_Allergist_Initial_Visit"
},
"End_Allergist_Initial_Visit": {
"type": "EncounterEnd",
"direct_transition": "Living_With_Allergies"
},
"Living_With_Allergies": {
"type": "Guard",
"remarks": [
"======================================================================",
" LIVING WITH ALLERGIES ",
"======================================================================",
"Whatever allergies the patients have, they will continue to passively ",
"live with them until an allergic condition or a severe reaction ",
"prompts a visit to their PCP and a referral to an allergist. Allergies ",
"aren't officially diagnosed until after an allergy test is performed.",
"For patient's 12 or older we can consider immunotherapy. This will ",
"not work for everyone but it's worth discussing. Immunotherapy is not ",
"an option before 1990."
],
"allow": {
"condition_type": "And",
"conditions": [
{
"condition_type": "Age",
"operator": ">",
"quantity": 12,
"unit": "years"
},
{
"condition_type": "Date",
"operator": ">=",
"year": 1990
},
{
"condition_type": "Attribute",
"attribute": "immunotherapy_status",
"operator": "is nil"
}
]
},
"direct_transition": "Immunotherapy_Submodule"
},
"Immunotherapy_Submodule": {
"type": "CallSubmodule",
"remarks": [
"This submodule may or may not give the patient immunotherapy. If ",
"immunotherapy is given a series of 60 treatments will be provided ",
"over the course of 3-5 years."
],
"submodule": "allergies/immunotherapy",
"direct_transition": "Living_With_Allergies"
},
"Allergy_Unspecified": {
"allergy_type": "allergy",
"category": "environment",
"type": "AllergyOnset",
"target_encounter": "Allergist_Initial_Visit",
"codes": [
{
"system": "SNOMED-CT",
"code": 419199007,
"display": "Allergy to substance (finding)"
}
],
"reactions": [],
"direct_transition": "Delay_For_Allergist_Initial_Visit",
"assign_to_attribute": "allergy_unspecified"
}
},
"gmf_version": 1
}

View File

@@ -0,0 +1,928 @@
{
"name": "Allergy Panel",
"remarks": [
"This submodule explicity references states in the 'Allergies and Treatment' module. ",
"In the future an Active Condition test should be favored instead of PriorState once ",
"there's a distinction between an 'Active' and 'Diagnosed' condition.",
"Most of these tests measure the amount of IgE Ab antibody in serum. ",
"http://www.mayomedicallaboratories.com/interpretive-guide/?alpha=S&unit_code=82716",
"IgE Ab < 0.35 kU/L == Negative Result ",
"IgE Ab > 0.70 kU/L == Positive ",
"IgE Ab > 17.5 kU/L == Strongly Positive ",
"The following allergens are tested here, and expected to be onset in allergies.json: ",
"Peanut, Treenut, Fish, Shellfish, Wheat, Egg, Dairy, Tree Pollen, Grass Pollen, ",
"Pet Dander, Dust Mite, Mold, Bee, Latex"
],
"states": {
"Initial": {
"type": "Initial",
"direct_transition": "Peanut_Test"
},
"Peanut_Test": {
"type": "Simple",
"remarks": [
"======================================================================",
" PEANUT ALLERGY TEST ",
"======================================================================"
],
"conditional_transition": [
{
"condition": {
"condition_type": "Active Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "91935009",
"display": "Allergy to peanut (finding)"
}
]
},
"transition": "Peanut_Test_Positive"
},
{
"transition": "Peanut_Test_Negative"
}
]
},
"Peanut_Test_Positive": {
"type": "Observation",
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "6206-7",
"display": "Peanut IgE Ab [Units/volume] in Serum"
}
],
"unit": "kU/L",
"range": {
"low": 0.7,
"high": 100
},
"direct_transition": "Nut_Test"
},
"Peanut_Test_Negative": {
"type": "Observation",
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "6206-7",
"display": "Peanut IgE Ab [Units/volume] in Serum"
}
],
"unit": "kU/L",
"range": {
"low": 0,
"high": 0.35
},
"direct_transition": "Nut_Test"
},
"Nut_Test": {
"type": "Simple",
"remarks": [
"======================================================================",
" NUT ALLERGY TEST ",
"======================================================================"
],
"conditional_transition": [
{
"condition": {
"condition_type": "Active Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "91934008",
"display": "Allergy to nut (finding)"
}
]
},
"transition": "Nut_Test_Positive"
},
{
"transition": "Nut_Test_Negative"
}
]
},
"Nut_Test_Positive": {
"type": "Observation",
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "6273-7",
"display": "Walnut IgE Ab [Units/volume] in Serum"
}
],
"unit": "kU/L",
"range": {
"low": 0.7,
"high": 100
},
"direct_transition": "Fish_Test"
},
"Nut_Test_Negative": {
"type": "Observation",
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "6273-7",
"display": "Walnut IgE Ab [Units/volume] in Serum"
}
],
"unit": "kU/L",
"range": {
"low": 0,
"high": 0.35
},
"direct_transition": "Fish_Test"
},
"Fish_Test": {
"type": "Simple",
"remarks": [
"======================================================================",
" FISH ALLERGY TEST ",
"======================================================================"
],
"conditional_transition": [
{
"condition": {
"condition_type": "Active Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "417532002",
"display": "Allergy to fish (finding)"
}
]
},
"transition": "Fish_Test_Positive"
},
{
"transition": "Fish_Test_Negative"
}
]
},
"Fish_Test_Positive": {
"type": "Observation",
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "6082-2",
"display": "Codfish IgE Ab [Units/volume] in Serum"
}
],
"unit": "kU/L",
"range": {
"low": 0.7,
"high": 100
},
"direct_transition": "Shellfish_Test"
},
"Fish_Test_Negative": {
"type": "Observation",
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "6082-2",
"display": "Codfish IgE Ab [Units/volume] in Serum"
}
],
"unit": "kU/L",
"range": {
"low": 0,
"high": 0.35
},
"direct_transition": "Shellfish_Test"
},
"Shellfish_Test": {
"type": "Simple",
"remarks": [
"======================================================================",
" SHELLFISH ALLERGY TEST ",
"======================================================================",
"There were LOINC codes available for shrimp, scallops, and clam. ",
"I chose to include only the shrimp test at this time."
],
"conditional_transition": [
{
"condition": {
"condition_type": "Active Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "300913006",
"display": "Allergy to shellfish (finding)"
}
]
},
"transition": "Shellfish_Test_Positive"
},
{
"transition": "Shellfish_Test_Negative"
}
]
},
"Shellfish_Test_Positive": {
"type": "Observation",
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "6246-3",
"display": "Shrimp IgE Ab [Units/volume] in Serum"
}
],
"unit": "kU/L",
"range": {
"low": 0.7,
"high": 100
},
"direct_transition": "Wheat_Test"
},
"Shellfish_Test_Negative": {
"type": "Observation",
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "6246-3",
"display": "Shrimp IgE Ab [Units/volume] in Serum"
}
],
"unit": "kU/L",
"range": {
"low": 0,
"high": 0.35
},
"direct_transition": "Wheat_Test"
},
"Wheat_Test": {
"type": "Simple",
"remarks": [
"======================================================================",
" WHEAT ALLERGY TEST ",
"======================================================================"
],
"conditional_transition": [
{
"condition": {
"condition_type": "Active Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "420174000",
"display": "Allergy to wheat (finding)"
}
]
},
"transition": "Wheat_Test_Positive"
},
{
"transition": "Wheat_Test_Negative"
}
]
},
"Wheat_Test_Positive": {
"type": "Observation",
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "6276-0",
"display": "Wheat IgE Ab [Units/volume] in Serum"
}
],
"unit": "kU/L",
"range": {
"low": 0.7,
"high": 100
},
"direct_transition": "Egg_Test"
},
"Wheat_Test_Negative": {
"type": "Observation",
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "6276-0",
"display": "Wheat IgE Ab [Units/volume] in Serum"
}
],
"unit": "kU/L",
"range": {
"low": 0,
"high": 0.35
},
"direct_transition": "Egg_Test"
},
"Egg_Test": {
"type": "Simple",
"remarks": [
"======================================================================",
" EGG ALLERGY TEST ",
"======================================================================"
],
"conditional_transition": [
{
"condition": {
"condition_type": "Active Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "213020009",
"display": "Allergy to egg protein (finding)"
}
]
},
"transition": "Egg_Test_Positive"
},
{
"transition": "Egg_Test_Negative"
}
]
},
"Egg_Test_Positive": {
"type": "Observation",
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "6106-9",
"display": "Egg white IgE Ab [Units/volume] in Serum"
}
],
"unit": "kU/L",
"range": {
"low": 0.7,
"high": 100
},
"direct_transition": "Soy_Test"
},
"Egg_Test_Negative": {
"type": "Observation",
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "6106-9",
"display": "Egg white IgE Ab [Units/volume] in Serum"
}
],
"unit": "kU/L",
"range": {
"low": 0,
"high": 0.35
},
"direct_transition": "Soy_Test"
},
"Soy_Test": {
"type": "Simple",
"remarks": [
"======================================================================",
" SOY ALLERGY TEST ",
"======================================================================"
],
"conditional_transition": [
{
"condition": {
"condition_type": "Active Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "782594005",
"display": "Allergy to soy protein (finding)"
}
]
},
"transition": "Soy_Test_Positive"
},
{
"transition": "Soy_Test_Negative"
}
]
},
"Soy_Test_Positive": {
"type": "Observation",
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "6248-9",
"display": "Soybean IgE Ab [Units/volume] in Serum"
}
],
"unit": "kU/L",
"range": {
"low": 0.7,
"high": 100
},
"direct_transition": "Milk_Test"
},
"Soy_Test_Negative": {
"type": "Observation",
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "6248-9",
"display": "Soybean IgE Ab [Units/volume] in Serum"
}
],
"unit": "kU/L",
"range": {
"low": 0,
"high": 0.35
},
"direct_transition": "Milk_Test"
},
"Milk_Test": {
"type": "Simple",
"remarks": [
"======================================================================",
" DAIRY ALLERGY TEST ",
"======================================================================"
],
"conditional_transition": [
{
"condition": {
"condition_type": "Active Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "414285001",
"display": "Allergy to food (finding)"
}
]
},
"transition": "Milk_Test_Positive"
},
{
"transition": "Milk_Test_Negative"
}
]
},
"Milk_Test_Positive": {
"type": "Observation",
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "7258-7",
"display": "Cow milk IgE Ab [Units/volume] in Serum"
}
],
"unit": "kU/L",
"range": {
"low": 0.7,
"high": 100
},
"direct_transition": "Tree_Test"
},
"Milk_Test_Negative": {
"type": "Observation",
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "7258-7",
"display": "Cow milk IgE Ab [Units/volume] in Serum"
}
],
"unit": "kU/L",
"range": {
"low": 0,
"high": 0.35
},
"direct_transition": "Tree_Test"
},
"Tree_Test": {
"type": "Simple",
"remarks": [
"======================================================================",
" TREE ALLERGY TEST ",
"======================================================================"
],
"conditional_transition": [
{
"condition": {
"condition_type": "Active Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "419263009",
"display": "Allergy to tree pollen (finding)"
}
]
},
"transition": "Tree_Test_Positive"
},
{
"transition": "Tree_Test_Negative"
}
]
},
"Tree_Test_Positive": {
"type": "Observation",
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "6189-5",
"display": "White oak IgE Ab [Units/volume] in Serum"
}
],
"unit": "kU/L",
"range": {
"low": 0.7,
"high": 100
},
"direct_transition": "Grass_Test"
},
"Tree_Test_Negative": {
"type": "Observation",
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "6189-5",
"display": "White oak IgE Ab [Units/volume] in Serum"
}
],
"unit": "kU/L",
"range": {
"low": 0,
"high": 0.35
},
"direct_transition": "Grass_Test"
},
"Grass_Test": {
"type": "Simple",
"remarks": [
"======================================================================",
" GRASS ALLERGY TEST ",
"======================================================================"
],
"conditional_transition": [
{
"condition": {
"condition_type": "Active Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "418689008",
"display": "Allergy to grass pollen (finding)"
}
]
},
"transition": "Grass_Test_Positive"
},
{
"transition": "Grass_Test_Negative"
}
]
},
"Grass_Test_Positive": {
"type": "Observation",
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "6085-5",
"display": "Common Ragweed IgE Ab [Units/volume] in Serum"
}
],
"unit": "kU/L",
"range": {
"low": 0.7,
"high": 100
},
"direct_transition": "Dander_Test"
},
"Grass_Test_Negative": {
"type": "Observation",
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "6085-5",
"display": "Common Ragweed IgE Ab [Units/volume] in Serum"
}
],
"unit": "kU/L",
"range": {
"low": 0,
"high": 0.35
},
"direct_transition": "Dander_Test"
},
"Dander_Test": {
"type": "Simple",
"remarks": [
"======================================================================",
" PET DANDER ALLERGY TEST ",
"======================================================================"
],
"conditional_transition": [
{
"condition": {
"condition_type": "Active Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "717234006",
"display": "Allergy to animal protein (finding)"
}
]
},
"transition": "Dander_Test_Positive"
},
{
"transition": "Dander_Test_Negative"
}
]
},
"Dander_Test_Positive": {
"type": "Observation",
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "6833-8",
"display": "Cat dander IgE Ab [Units/volume] in Serum"
}
],
"unit": "kU/L",
"range": {
"low": 0.7,
"high": 100
},
"direct_transition": "Mite_Test"
},
"Dander_Test_Negative": {
"type": "Observation",
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "6833-8",
"display": "Cat dander IgE Ab [Units/volume] in Serum"
}
],
"unit": "kU/L",
"range": {
"low": 0,
"high": 0.35
},
"direct_transition": "Mite_Test"
},
"Mite_Test": {
"type": "Simple",
"remarks": [
"======================================================================",
" MITE ALLERGY TEST ",
"======================================================================"
],
"conditional_transition": [
{
"condition": {
"condition_type": "Active Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "232350006",
"display": "Allergy to dust mite protein (finding)"
}
]
},
"transition": "Mite_Test_Positive"
},
{
"transition": "Mite_Test_Negative"
}
]
},
"Mite_Test_Positive": {
"type": "Observation",
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "6095-4",
"display": "American house dust mite IgE Ab [Units/volume] in Serum"
}
],
"unit": "kU/L",
"range": {
"low": 0.7,
"high": 100
},
"direct_transition": "Mold_Test"
},
"Mite_Test_Negative": {
"type": "Observation",
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "6095-4",
"display": "American house dust mite IgE Ab [Units/volume] in Serum"
}
],
"unit": "kU/L",
"range": {
"low": 0,
"high": 0.35
},
"direct_transition": "Mold_Test"
},
"Mold_Test": {
"type": "Simple",
"remarks": [
"======================================================================",
" MOLD ALLERGY TEST ",
"======================================================================"
],
"conditional_transition": [
{
"condition": {
"condition_type": "Active Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "419474003",
"display": "Allergy to mold (finding)"
}
]
},
"transition": "Mold_Test_Positive"
},
{
"transition": "Mold_Test_Negative"
}
]
},
"Mold_Test_Positive": {
"type": "Observation",
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "6075-6",
"display": "Cladosporium herbarum IgE Ab [Units/volume] in Serum"
}
],
"unit": "kU/L",
"range": {
"low": 0.7,
"high": 100
},
"direct_transition": "Bee_Test"
},
"Mold_Test_Negative": {
"type": "Observation",
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "6075-6",
"display": "Cladosporium herbarum IgE Ab [Units/volume] in Serum"
}
],
"unit": "kU/L",
"range": {
"low": 0,
"high": 0.35
},
"direct_transition": "Bee_Test"
},
"Bee_Test": {
"type": "Simple",
"remarks": [
"======================================================================",
" BEE ALLERGY TEST ",
"======================================================================"
],
"conditional_transition": [
{
"condition": {
"condition_type": "Active Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "424213003",
"display": "Allergy to bee venom (finding)"
}
]
},
"transition": "Bee_Test_Positive"
},
{
"transition": "Bee_Test_Negative"
}
]
},
"Bee_Test_Positive": {
"type": "Observation",
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "6844-5",
"display": "Honey bee IgE Ab [Units/volume] in Serum"
}
],
"unit": "kU/L",
"range": {
"low": 0.7,
"high": 100
},
"direct_transition": "Latex_Test"
},
"Bee_Test_Negative": {
"type": "Observation",
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "6844-5",
"display": "Honey bee IgE Ab [Units/volume] in Serum"
}
],
"unit": "kU/L",
"range": {
"low": 0,
"high": 0.35
},
"direct_transition": "Latex_Test"
},
"Latex_Test": {
"type": "Simple",
"remarks": [
"======================================================================",
" LATEX ALLERGY TEST ",
"======================================================================"
],
"conditional_transition": [
{
"condition": {
"condition_type": "Active Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "1003755004",
"display": "Allergy to Hevea brasiliensis latex protein (finding)"
}
]
},
"transition": "Latex_Test_Positive"
},
{
"transition": "Latex_Test_Negative"
}
]
},
"Latex_Test_Positive": {
"type": "Observation",
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "6158-0",
"display": "Latex IgE Ab [Units/volume] in Serum"
}
],
"unit": "kU/L",
"range": {
"low": 0.7,
"high": 100
},
"direct_transition": "Allergy_Test_Terminal"
},
"Latex_Test_Negative": {
"type": "Observation",
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "6158-0",
"display": "Latex IgE Ab [Units/volume] in Serum"
}
],
"unit": "kU/L",
"range": {
"low": 0,
"high": 0.35
},
"direct_transition": "Allergy_Test_Terminal"
},
"Allergy_Test_Terminal": {
"type": "Terminal"
}
},
"gmf_version": 1
}

View File

@@ -0,0 +1,812 @@
{
"name": "Drug_Allergies",
"remarks": [
"This submodule onsets various drug allergies and is intended to be called by the main allergies module."
],
"states": {
"Initial": {
"type": "Initial",
"direct_transition": "Penicillin_Allergy"
},
"Terminal": {
"type": "Terminal"
},
"Penicillin_Allergy": {
"type": "Simple",
"remarks": [
"Actual penicillin allergies happen in about 1% of individuals.",
"About 10% of people have a penicillin allergy listed in the medical record.",
"This will set an attribute indicating a real allergy on 1% of people, but ensure that 10% have allergies in their record.",
"https://www.cdc.gov/antibiotic-use/community/pdfs/penicillin-factsheet.pdf"
],
"distributed_transition": [
{
"transition": "True_Penicillin_Allergy",
"distribution": 0.01
},
{
"transition": "Penicillin_Allergy_Onset",
"distribution": 0.09
},
{
"transition": "Aspirin_Allergy_Intolerance",
"distribution": 0.9
}
]
},
"True_Penicillin_Allergy": {
"type": "SetAttribute",
"attribute": "Penicillin_Allergy",
"direct_transition": "Penicillin_Allergy_Onset",
"value": true
},
"Penicillin_Allergy_Onset": {
"type": "AllergyOnset",
"allergy_type": "allergy",
"category": "medication",
"target_encounter": "Allergist_Initial_Visit",
"codes": [
{
"system": "RxNorm",
"code": 7984,
"display": "Penicillin V"
}
],
"reactions": [
{
"reaction": {
"system": "SNOMED-CT",
"code": "49727002",
"display": "Cough (finding)"
},
"possible_severities": [
{
"level": "moderate",
"value": 0.05
},
{
"level": "none",
"value": 0.95
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "402387002",
"display": "Allergic angioedema (disorder)"
},
"possible_severities": [
{
"level": "mild",
"value": 0.11
},
{
"level": "none",
"value": 0.89
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "404640003",
"display": "Dizziness (finding)"
},
"possible_severities": [
{
"level": "mild",
"value": 0.01
},
{
"level": "none",
"value": 0.99
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "267036007",
"display": "Dyspnea (finding)"
},
"possible_severities": [
{
"level": "mild",
"value": 0.06
},
{
"level": "none",
"value": 0.94
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "247472004",
"display": "Wheal (finding)"
},
"possible_severities": [
{
"level": "mild",
"value": 0.52
},
{
"level": "none",
"value": 0.48
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "39579001",
"display": "Anaphylaxis (disorder)"
},
"possible_severities": [
{
"level": "severe",
"value": 0.03
},
{
"level": "none",
"value": 0.97
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "271807003",
"display": "Eruption of skin (disorder)"
},
"possible_severities": [
{
"level": "mild",
"value": 0.34
},
{
"level": "none",
"value": 0.6599999999999999
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "878820003",
"display": "Rhinoconjunctivitis (disorder)"
},
"possible_severities": [
{
"level": "moderate",
"value": 0.04
},
{
"level": "none",
"value": 0.96
}
]
}
],
"direct_transition": "Aspirin_Allergy_Intolerance"
},
"Aspirin_Allergy_Intolerance": {
"type": "Simple",
"remarks": [
"About 1% of individuals have an allergy to aspirin",
"About 20% of individuals have an intolerance",
""
],
"distributed_transition": [
{
"transition": "Aspirin_Allergy_Onset",
"distribution": 0.2
},
{
"transition": "NSAID_Allergy",
"distribution": 0.8
}
]
},
"Aspirin_Allergy_Onset": {
"type": "AllergyOnset",
"allergy_type": "allergy",
"category": "medication",
"target_encounter": "Allergist_Initial_Visit",
"codes": [
{
"system": "RxNorm",
"code": 1191,
"display": "Aspirin"
}
],
"reactions": [
{
"reaction": {
"system": "SNOMED-CT",
"code": "247472004",
"display": "Wheal (finding)"
},
"possible_severities": [
{
"level": "moderate",
"value": 0.19
},
{
"level": "none",
"value": 0.81
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "402387002",
"display": "Allergic angioedema (disorder)"
},
"possible_severities": [
{
"level": "moderate",
"value": 0.05
},
{
"level": "none",
"value": 0.95
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "39579001",
"display": "Anaphylaxis (disorder)"
},
"possible_severities": [
{
"level": "severe",
"value": 0.028
},
{
"level": "none",
"value": 0.972
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "21522001",
"display": "Abdominal pain (finding)"
},
"possible_severities": [
{
"level": "moderate",
"value": 0.32
},
{
"level": "none",
"value": 0.68
}
]
}
],
"direct_transition": "NSAID_Allergy"
},
"NSAID_Allergy": {
"type": "Simple",
"remarks": [
"1.6% of people have a Non-steroidal anti-inflammatory drugs (NSAIDs), ibuprofen allergy.",
"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC6004000/"
],
"distributed_transition": [
{
"transition": "Onset_Ibuprofen_Allergy",
"distribution": 0.016
},
{
"transition": "Sulfa_Drug_Allergy",
"distribution": 0.984
}
]
},
"Sulfa_Drug_Allergy": {
"type": "Simple",
"remarks": [
"Allergy to sulfa drugs occurs in 3% - 8% of the population. We will give it to 5% of individuals.",
"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC6789825/",
""
],
"distributed_transition": [
{
"transition": "Onset_Sulfa_Drug_Allergy",
"distribution": 0.05
},
{
"transition": "Cephalosporin_Allergy",
"distribution": 0.95
}
]
},
"Onset_Ibuprofen_Allergy": {
"type": "AllergyOnset",
"allergy_type": "allergy",
"category": "medication",
"target_encounter": "Allergist_Initial_Visit",
"codes": [
{
"system": "RxNorm",
"code": "5640",
"display": "Ibuprofen"
}
],
"reactions": [
{
"reaction": {
"system": "SNOMED-CT",
"code": "418290006",
"display": "Itching (finding)"
},
"possible_severities": [
{
"level": "moderate",
"value": 0.4
},
{
"level": "none",
"value": 0.6
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "247472004",
"display": "Wheal (finding)"
},
"possible_severities": [
{
"level": "moderate",
"value": 0.29
},
{
"level": "none",
"value": 0.71
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "271811009",
"display": "Face goes red (finding)"
},
"possible_severities": [
{
"level": "moderate",
"value": 0.15
},
{
"level": "none",
"value": 0.85
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "878820003",
"display": "Rhinoconjunctivitis (disorder)"
},
"possible_severities": [
{
"level": "moderate",
"value": 0.3
},
{
"level": "none",
"value": 0.7
}
]
}
],
"direct_transition": "Sulfa_Drug_Allergy"
},
"Onset_Sulfa_Drug_Allergy": {
"type": "AllergyOnset",
"allergy_type": "allergy",
"category": "medication",
"target_encounter": "Allergist_Initial_Visit",
"codes": [
{
"system": "RxNorm",
"code": "10831",
"display": "Sulfamethoxazole / Trimethoprim"
}
],
"reactions": [
{
"reaction": {
"system": "SNOMED-CT",
"code": "402387002",
"display": "Allergic angioedema (disorder)"
},
"possible_severities": [
{
"level": "mild",
"value": 0.126
},
{
"level": "none",
"value": 0.874
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "247472004",
"display": "Wheal (finding)"
},
"possible_severities": [
{
"level": "moderate",
"value": 0.46
},
{
"level": "none",
"value": 0.54
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "39579001",
"display": "Anaphylaxis (disorder)"
},
"possible_severities": [
{
"level": "severe",
"value": 0.01
},
{
"level": "none",
"value": 0.99
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "271807003",
"display": "Eruption of skin (disorder)"
},
"possible_severities": [
{
"level": "moderate",
"value": 0.63
},
{
"level": "none",
"value": 0.37
}
]
}
],
"direct_transition": "Cephalosporin_Allergy"
},
"Cephalosporin_Allergy": {
"type": "Simple",
"remarks": [
"1% to 3% of individuals are allergic to cphalosporins. This module sets it fo 2% of people."
],
"distributed_transition": [
{
"transition": "Onset_Cephalosporin_Allergy",
"distribution": 0.02
},
{
"transition": "ACE_Inhibitor_Intolerance",
"distribution": 0.98
}
]
},
"Onset_Cephalosporin_Allergy": {
"type": "AllergyOnset",
"allergy_type": "allergy",
"category": "medication",
"target_encounter": "Allergist_Initial_Visit",
"codes": [
{
"system": "RxNorm",
"code": "25037",
"display": "cefdinir"
},
{
"system": "RxNorm",
"code": "25033",
"display": "Cefixime"
},
{
"system": "RxNorm",
"code": "20489",
"display": "cefpodoxime"
},
{
"system": "RxNorm",
"code": "2191",
"display": "Ceftazidime"
},
{
"system": "RxNorm",
"code": "2193",
"display": "Ceftriaxone"
},
{
"system": "RxNorm",
"code": "2180",
"display": "Cefazolin"
},
{
"system": "RxNorm",
"code": "2231",
"display": "Cephalexin"
},
{
"system": "RxNorm",
"code": "2176",
"display": "Cefaclor"
},
{
"system": "RxNorm",
"code": "20481",
"display": "cefepime"
},
{
"system": "RxNorm",
"code": "2189",
"display": "Cefoxitin"
},
{
"system": "RxNorm",
"code": "2194",
"display": "Cefuroxime"
}
],
"reactions": [
{
"reaction": {
"system": "SNOMED-CT",
"code": "402387002",
"display": "Allergic angioedema (disorder)"
},
"possible_severities": [
{
"level": "moderate",
"value": 0.08
},
{
"level": "none",
"value": 0.92
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "247472004",
"display": "Wheal (finding)"
},
"possible_severities": [
{
"level": "moderate",
"value": 0.08
},
{
"level": "none",
"value": 0.92
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "39579001",
"display": "Anaphylaxis (disorder)"
},
"possible_severities": [
{
"level": "severe",
"value": 0.2
},
{
"level": "none",
"value": 0.8
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "271807003",
"display": "Eruption of skin (disorder)"
},
"possible_severities": [
{
"level": "moderate",
"value": 0.2
},
{
"level": "none",
"value": 0.8
}
]
}
],
"direct_transition": "ACE_Inhibitor_Intolerance"
},
"ACE_Inhibitor_Intolerance": {
"type": "Simple",
"remarks": [
"11.48% of individuals have an intolerance to ACE inhibitors.",
"https://www.sciencedirect.com/science/article/pii/S0735109718304315?viewFullText=true"
],
"distributed_transition": [
{
"transition": "Onset_ACE_Inhibitor_Intolerance",
"distribution": 0.1148
},
{
"transition": "Terminal",
"distribution": 0.8852
}
]
},
"Onset_ACE_Inhibitor_Intolerance": {
"type": "AllergyOnset",
"allergy_type": "intolerance",
"category": "medication",
"target_encounter": "Allergist_Initial_Visit",
"codes": [
{
"system": "RxNorm",
"code": "29046",
"display": "Lisinopril"
},
{
"system": "RxNorm",
"code": "1998",
"display": "Captopril"
},
{
"system": "RxNorm",
"code": "3827",
"display": "Enalapril"
},
{
"system": "RxNorm",
"code": "18867",
"display": "benazepril"
},
{
"system": "RxNorm",
"code": "35208",
"display": "quinapril"
},
{
"system": "RxNorm",
"code": "35296",
"display": "Ramipril"
}
],
"reactions": [
{
"reaction": {
"system": "SNOMED-CT",
"code": "49727002",
"display": "Cough (finding)"
},
"possible_severities": [
{
"level": "moderate",
"value": 0.2
},
{
"level": "none",
"value": 0.8
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "402387002",
"display": "Allergic angioedema (disorder)"
},
"possible_severities": [
{
"level": "moderate",
"value": 0.007
},
{
"level": "none",
"value": 0.993
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "404640003",
"display": "Dizziness (finding)"
},
"possible_severities": [
{
"level": "mild",
"value": 0.002
},
{
"level": "none",
"value": 0.998
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "236428007",
"display": "Acute kidney injury due to nephrotoxicity (disorder)"
},
"possible_severities": [
{
"level": "severe",
"value": 0.008
},
{
"level": "none",
"value": 0.992
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "267036007",
"display": "Dyspnea (finding)"
},
"possible_severities": [
{
"level": "moderate",
"value": 0.06
},
{
"level": "none",
"value": 0.94
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "237849008",
"display": "Drug-induced hyperkalemia (disorder)"
},
"possible_severities": [
{
"level": "moderate",
"value": 0.04
},
{
"level": "none",
"value": 0.96
}
]
}
],
"direct_transition": "Terminal"
}
},
"gmf_version": 2
}

View File

@@ -0,0 +1,717 @@
{
"name": "Environmental Allergy Incidence",
"remarks": [
"This submodule onsets various allergies and is intended to be called ",
"by the main allergies module."
],
"states": {
"Initial": {
"type": "Initial",
"direct_transition": "Chance_of_Tree_Pollen_Allergy"
},
"Chance_of_Tree_Pollen_Allergy": {
"type": "Simple",
"remarks": [
"======================================================================",
" TREE POLLEN ALLERGY ",
"======================================================================",
"At present, up to 20% of children are diagnosed with a tree pollen allergy. ",
"Source: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4098757/",
"In this model most of those children are also atopic, aligning with the ",
"prevalence of allergic rhinitis."
],
"complex_transition": [
{
"condition": {
"condition_type": "Attribute",
"attribute": "atopic",
"operator": "is not nil"
},
"distributions": [
{
"distribution": 0.85,
"transition": "Tree_Pollen_Allergy"
},
{
"distribution": 0.15,
"transition": "Chance_of_Grass_Pollen_Allergy"
}
]
},
{
"distributions": [
{
"distribution": 0.03,
"transition": "Tree_Pollen_Allergy"
},
{
"distribution": 0.97,
"transition": "Chance_of_Grass_Pollen_Allergy"
}
]
}
]
},
"Tree_Pollen_Allergy": {
"type": "AllergyOnset",
"allergy_type": "allergy",
"category": "environment",
"target_encounter": "Allergist_Initial_Visit",
"codes": [
{
"system": "SNOMED-CT",
"code": "782576004",
"display": "Tree pollen (substance)"
}
],
"direct_transition": "Chance_of_Grass_Pollen_Allergy"
},
"Chance_of_Grass_Pollen_Allergy": {
"type": "Simple",
"remarks": [
"======================================================================",
" GRASS POLLEN ALLERGY ",
"======================================================================",
"At present, up to 20% of children are diagnosed with a grass pollen allergy. ",
"Source: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4098757/",
"In this model most of those children are also atopic, aligning with the ",
"prevalence of allergic rhinitis."
],
"complex_transition": [
{
"condition": {
"condition_type": "Attribute",
"attribute": "atopic",
"operator": "is not nil"
},
"distributions": [
{
"distribution": 0.85,
"transition": "Grass_Pollen_Allergy"
},
{
"distribution": 0.15,
"transition": "Chance_of_Pet_Dander_Allergy"
}
]
},
{
"distributions": [
{
"distribution": 0.03,
"transition": "Grass_Pollen_Allergy"
},
{
"distribution": 0.97,
"transition": "Chance_of_Pet_Dander_Allergy"
}
]
}
]
},
"Grass_Pollen_Allergy": {
"type": "AllergyOnset",
"allergy_type": "allergy",
"category": "environment",
"target_encounter": "Allergist_Initial_Visit",
"codes": [
{
"system": "SNOMED-CT",
"code": "256277009",
"display": "Grass pollen (substance)"
}
],
"direct_transition": "Chance_of_Pet_Dander_Allergy"
},
"Chance_of_Pet_Dander_Allergy": {
"type": "Simple",
"remarks": [
"======================================================================",
" PET DANDER ALLERGY ",
"======================================================================",
"At present, up to 30% of people are diagnosed with a pet dander allergy. ",
"Source: http://allergicliving.com/2010/07/02/pet-allergies-a-gander-at-dander/",
"In this model most of these people are also atopic, aligning with the ",
"prevalence of allergic rhinitis and asthma."
],
"complex_transition": [
{
"condition": {
"condition_type": "Attribute",
"attribute": "atopic",
"operator": "is not nil"
},
"distributions": [
{
"distribution": 1,
"transition": "Pet_Dander_Allergy"
}
]
},
{
"distributions": [
{
"distribution": 0.1,
"transition": "Pet_Dander_Allergy"
},
{
"distribution": 0.9,
"transition": "Chance_of_Dust_Mite_Allergy"
}
]
}
]
},
"Pet_Dander_Allergy": {
"type": "AllergyOnset",
"allergy_type": "allergy",
"category": "environment",
"target_encounter": "Allergist_Initial_Visit",
"codes": [
{
"system": "SNOMED-CT",
"code": "264287008",
"display": "Animal dander (substance)"
}
],
"reactions": [
{
"reaction": {
"system": "SNOMED-CT",
"code": "49727002",
"display": "Cough (finding)"
},
"possible_severities": [
{
"level": "moderate",
"value": 0.23
},
{
"level": "none",
"value": 0.77
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "267036007",
"display": "Dyspnea (finding)"
},
"possible_severities": [
{
"level": "mild",
"value": 0.2
},
{
"level": "none",
"value": 0.8
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "247472004",
"display": "Wheal (finding)"
},
"possible_severities": [
{
"level": "mild",
"value": 0.36
},
{
"level": "none",
"value": 0.64
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "271807003",
"display": "Eruption of skin (disorder)"
},
"possible_severities": [
{
"level": "mild",
"value": 0.53
},
{
"level": "none",
"value": 0.47
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "878820003",
"display": "Rhinoconjunctivitis (disorder)"
},
"possible_severities": [
{
"level": "moderate",
"value": 0.8
},
{
"level": "none",
"value": 0.19999999999999996
}
]
}
],
"direct_transition": "Chance_of_Dust_Mite_Allergy"
},
"Chance_of_Dust_Mite_Allergy": {
"type": "Simple",
"remarks": [
"======================================================================",
" DUST MITE ALLERGY ",
"======================================================================",
"About 85% of all atopic patients have mite allergies. ",
"Source: https://www.ncbi.nlm.nih.gov/pubmed/12190652"
],
"complex_transition": [
{
"condition": {
"condition_type": "Attribute",
"attribute": "atopic",
"operator": "is not nil"
},
"distributions": [
{
"distribution": 0.85,
"transition": "Dust_Mite_Allergy"
},
{
"distribution": 0.15,
"transition": "Chance_of_Mold_Allergy"
}
]
},
{
"distributions": [
{
"distribution": 0.02,
"transition": "Dust_Mite_Allergy"
},
{
"distribution": 0.98,
"transition": "Chance_of_Mold_Allergy"
}
]
}
]
},
"Dust_Mite_Allergy": {
"type": "AllergyOnset",
"allergy_type": "allergy",
"category": "environment",
"target_encounter": "Allergist_Initial_Visit",
"codes": [
{
"system": "SNOMED-CT",
"code": "260147004",
"display": "House dust mite (organism)"
}
],
"direct_transition": "Chance_of_Mold_Allergy"
},
"Chance_of_Mold_Allergy": {
"type": "Simple",
"remarks": [
"======================================================================",
" MOLD ALLERGY ",
"======================================================================",
"Sensitization to mold is very common, but symptoms are usually mild.",
"Source: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC1240910/"
],
"complex_transition": [
{
"condition": {
"condition_type": "Attribute",
"attribute": "atopic",
"operator": "is not nil"
},
"distributions": [
{
"distribution": 1,
"transition": "Mold_Allergy"
}
]
},
{
"distributions": [
{
"distribution": 0.15,
"transition": "Mold_Allergy"
},
{
"distribution": 0.85,
"transition": "Chance_of_Bee_Allergy"
}
]
}
]
},
"Mold_Allergy": {
"type": "AllergyOnset",
"allergy_type": "allergy",
"category": "environment",
"remarks": [
"Back to the American English spelling of mold."
],
"target_encounter": "Allergist_Initial_Visit",
"codes": [
{
"system": "SNOMED-CT",
"code": "84489001",
"display": "Mold (organism)"
}
],
"reactions": [
{
"reaction": {
"system": "SNOMED-CT",
"code": "21626009",
"display": "Cutaneous hypersensitivity (disorder)"
},
"possible_severities": [
{
"level": "mild",
"value": 0.292
},
{
"level": "none",
"value": 0.7
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "76067001",
"display": "Sneezing (finding)"
},
"possible_severities": [
{
"level": "mild",
"value": 0.139
},
{
"level": "none",
"value": 0.86
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "267101005",
"display": "Nasal discharge present (situation)"
},
"possible_severities": [
{
"level": "mild",
"value": 0.183
},
{
"level": "none",
"value": 0.81
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "56018004",
"display": "Wheezing (finding)"
},
"possible_severities": [
{
"level": "mild",
"value": 0.075
},
{
"level": "none",
"value": 0.92
}
]
}
],
"direct_transition": "Chance_of_Bee_Allergy"
},
"Chance_of_Bee_Allergy": {
"type": "Simple",
"remarks": [
"======================================================================",
" BEE STING ALLERGY ",
"======================================================================",
"Estimates range from 1-7%. Source: ",
"http://www.worldallergy.org/professional/allergic_diseases_center/insect_allergy/"
],
"complex_transition": [
{
"condition": {
"condition_type": "Attribute",
"attribute": "atopic",
"operator": "is not nil"
},
"distributions": [
{
"distribution": 0.33,
"transition": "Bee_Allergy"
},
{
"distribution": 0.67,
"transition": "Chance_of_Latex_Allergy"
}
]
},
{
"distributions": [
{
"distribution": 0.01,
"transition": "Bee_Allergy"
},
{
"distribution": 0.99,
"transition": "Chance_of_Latex_Allergy"
}
]
}
]
},
"Bee_Allergy": {
"type": "AllergyOnset",
"allergy_type": "allergy",
"category": "environment",
"target_encounter": "Allergist_Initial_Visit",
"codes": [
{
"system": "SNOMED-CT",
"code": "288328004",
"display": "Bee venom (substance)"
}
],
"reactions": [
{
"reaction": {
"system": "SNOMED-CT",
"code": "39579001",
"display": "Anaphylaxis (disorder)"
},
"possible_severities": [
{
"level": "severe",
"value": 0.03
},
{
"level": "none",
"value": 0.96
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "271807003",
"display": "Eruption of skin (disorder)"
},
"possible_severities": [
{
"level": "moderate",
"value": 0.264
},
{
"level": "none",
"value": 0.73
}
]
}
],
"direct_transition": "Chance_of_Latex_Allergy"
},
"Chance_of_Latex_Allergy": {
"type": "Simple",
"remarks": [
"======================================================================",
" LATEX ALLERGY ",
"======================================================================",
"Estimates range from 4-9%. Prevalence is especially high in healthcare ",
"workers and those who had frequent surgeries during childhood.",
"https://www.ncbi.nlm.nih.gov/pubmed/27010091"
],
"complex_transition": [
{
"condition": {
"condition_type": "Attribute",
"attribute": "atopic",
"operator": "is not nil"
},
"distributions": [
{
"distribution": 0.33,
"transition": "Latex_Allergy"
},
{
"distribution": 0.67,
"transition": "Environmental_Allergy_Incidence_Terminal"
}
]
},
{
"distributions": [
{
"distribution": 0.02,
"transition": "Latex_Allergy"
},
{
"distribution": 0.98,
"transition": "Environmental_Allergy_Incidence_Terminal"
}
]
}
]
},
"Latex_Allergy": {
"type": "AllergyOnset",
"allergy_type": "allergy",
"category": "environment",
"target_encounter": "Allergist_Initial_Visit",
"codes": [
{
"system": "SNOMED-CT",
"code": "111088007",
"display": "Latex (substance)"
}
],
"reactions": [
{
"reaction": {
"system": "SNOMED-CT",
"code": "402387002",
"display": "Allergic angioedema (disorder)"
},
"possible_severities": [
{
"level": "moderate",
"value": 0.17
},
{
"level": "none",
"value": 0.83
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "267036007",
"display": "Dyspnea (finding)"
},
"possible_severities": [
{
"level": "moderate",
"value": 0.1
},
{
"level": "none",
"value": 0.9
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "247472004",
"display": "Wheal (finding)"
},
"possible_severities": [
{
"level": "mild",
"value": 0.8
},
{
"level": "none",
"value": 0.19999999999999996
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "39579001",
"display": "Anaphylaxis (disorder)"
},
"possible_severities": [
{
"level": "severe",
"value": 0.13
},
{
"level": "none",
"value": 0.87
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "271807003",
"display": "Eruption of skin (disorder)"
},
"possible_severities": [
{
"level": "mild",
"value": 0.06
},
{
"level": "none",
"value": 0.94
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "878820003",
"display": "Rhinoconjunctivitis (disorder)"
},
"possible_severities": [
{
"level": "mild",
"value": 0.16
},
{
"level": "none",
"value": 0.84
}
]
},
{
"reaction": {
"system": "SNOMED-CT",
"code": "418290006",
"display": "Itching (finding)"
},
"possible_severities": [
{
"level": "moderate",
"value": 0.11
},
{
"level": "none",
"value": 0.89
}
]
}
],
"direct_transition": "Environmental_Allergy_Incidence_Terminal"
},
"Environmental_Allergy_Incidence_Terminal": {
"type": "Terminal"
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,267 @@
{
"name": "Allergy Immunotherapy",
"remarks": [
"This submodule is called by 'allergies.json'. This models a series of ",
"immunotherapy treatments designed to lessen the severity of allergy ",
"symptoms, or even eliminate the sensitivity altogether. ",
"Immunotherapy is most effective against outdoor allergens (trees, grass), ",
"and common indoor allergens (mold, mites, pet dander). Immunotherapy is ",
"minimally effective against food allergens."
],
"states": {
"Initial": {
"type": "Initial",
"direct_transition": "Immunotherapy_Consultation"
},
"Immunotherapy_Consultation": {
"type": "Encounter",
"remarks": [
"======================================================================",
" IMMUNOTHERAPY ",
"======================================================================",
"Allergen immunotherapy for hay fever has been common practice since the ",
"1930's. It was first proven by scientists in the UK in 1911. It has since ",
"been expanded to include additional environmental and food allergens."
],
"encounter_class": "ambulatory",
"codes": [
{
"system": "SNOMED-CT",
"code": "170837001",
"display": "Allergic disorder initial assessment (regime/therapy)"
}
],
"distributed_transition": [
{
"distribution": 0.75,
"transition": "Immunotherapy_Given"
},
{
"distribution": 0.25,
"transition": "Immunotherapy_Not_Given",
"remarks": [
"The distribution here is somewhat arbitrary. I could not find reasonable stats for",
"what percentage of people are given immunotherapy but it's not everyone.",
"I went with a 75/25 split. Reasons to not give immunotherapy include fear of needles,",
"pre-existing immune conditions (like AIDS), and prohibitive cost."
]
}
],
"reason": "allergy_unspecified"
},
"Immunotherapy_Given": {
"type": "SetAttribute",
"attribute": "immunotherapy_status",
"value": "given",
"direct_transition": "Immunotherapy_CarePlan"
},
"Immunotherapy_Not_Given": {
"type": "SetAttribute",
"attribute": "immunotherapy_status",
"value": "not-given",
"direct_transition": "End_Consultation"
},
"Immunotherapy_CarePlan": {
"type": "CarePlanStart",
"codes": [
{
"system": "SNOMED-CT",
"code": "170836005",
"display": "Allergic disorder monitoring (regime/therapy)"
}
],
"activities": [
{
"system": "SNOMED-CT",
"code": "182678001",
"display": "Allergen immunotherapy (regime/therapy)"
}
],
"direct_transition": "Benchmark_Allergy_Test"
},
"Benchmark_Allergy_Test": {
"type": "Procedure",
"duration": {
"low": 20,
"high": 40,
"unit": "minutes"
},
"codes": [
{
"system": "SNOMED-CT",
"code": "395142003",
"display": "Allergy screening test (procedure)"
}
],
"direct_transition": "Benchmark_Allergy_Panel"
},
"Benchmark_Allergy_Panel": {
"type": "CallSubmodule",
"submodule": "allergies/allergy_panel",
"direct_transition": "End_Consultation"
},
"End_Consultation": {
"type": "EncounterEnd",
"conditional_transition": [
{
"condition": {
"condition_type": "Attribute",
"attribute": "immunotherapy_status",
"operator": "==",
"value": "not-given"
},
"transition": "Terminal"
},
{
"transition": "Initialize_Immunotherapy_Counter"
}
]
},
"Initialize_Immunotherapy_Counter": {
"type": "SetAttribute",
"attribute": "immunotherapy_counter",
"value": 0,
"direct_transition": "Undergoing_Immunotherapy_Treatment"
},
"Undergoing_Immunotherapy_Treatment": {
"type": "Delay",
"remarks": [
"Patients get immunotherapy treatments for an average of 5 years.",
"Given monthly appointments we count a total of 60 appointments before ",
"ending the immunotherapy."
],
"range": {
"low": 3,
"high": 4,
"unit": "weeks"
},
"conditional_transition": [
{
"condition": {
"condition_type": "Attribute",
"attribute": "immunotherapy_counter",
"operator": "<",
"value": 60
},
"transition": "Immunotherapy_Treatment"
},
{
"transition": "Immunotherapy_Treatment_Complete"
}
]
},
"Immunotherapy_Treatment": {
"type": "Encounter",
"encounter_class": "ambulatory",
"codes": [
{
"system": "SNOMED-CT",
"code": "371883000",
"display": "Outpatient procedure (procedure)"
}
],
"direct_transition": "Immunotherapy_Procedure",
"reason": "allergy_unspecified"
},
"Immunotherapy_Procedure": {
"type": "Procedure",
"codes": [
{
"system": "SNOMED-CT",
"code": "180256009",
"display": "Subcutaneous immunotherapy (procedure)"
}
],
"duration": {
"low": 15,
"high": 60,
"unit": "minutes"
},
"direct_transition": "End_Treatment_Session"
},
"End_Treatment_Session": {
"type": "EncounterEnd",
"direct_transition": "Count_A_Treatment"
},
"Count_A_Treatment": {
"type": "Counter",
"action": "increment",
"attribute": "immunotherapy_counter",
"direct_transition": "Undergoing_Immunotherapy_Treatment"
},
"Immunotherapy_Treatment_Complete": {
"type": "Simple",
"direct_transition": "Immunotherapy_Followup"
},
"Immunotherapy_Followup": {
"type": "Encounter",
"encounter_class": "ambulatory",
"codes": [
{
"system": "SNOMED-CT",
"code": "170838006",
"display": "Allergic disorder follow-up assessment (regime/therapy)"
}
],
"direct_transition": "Immunotherapy_CarePlan_Ends",
"reason": "allergy_unspecified"
},
"Immunotherapy_CarePlan_Ends": {
"type": "CarePlanEnd",
"careplan": "Immunotherapy_CarePlan",
"direct_transition": "Immunotherapy_Success_Rate"
},
"Immunotherapy_Success_Rate": {
"type": "Simple",
"remarks": [
"My research has shown up to 85% of people respond positively to ",
"immunotherapy treatment. This allows patients to 'outgrow' their ",
"environmental allergies."
],
"distributed_transition": [
{
"distribution": 0.8,
"transition": "Outgrown_Environmental_Allergies"
},
{
"distribution": 0.2,
"transition": "Followup_Test"
}
]
},
"Outgrown_Environmental_Allergies": {
"type": "CallSubmodule",
"submodule": "allergies/outgrow_env_allergies",
"direct_transition": "Followup_Test"
},
"Followup_Test": {
"type": "Procedure",
"duration": {
"low": 20,
"high": 40,
"unit": "minutes"
},
"codes": [
{
"system": "SNOMED-CT",
"code": "395142003",
"display": "Allergy screening test (procedure)"
}
],
"direct_transition": "Followup_Allergy_Panel"
},
"Followup_Allergy_Panel": {
"type": "CallSubmodule",
"submodule": "allergies/allergy_panel",
"direct_transition": "Followup_End"
},
"Followup_End": {
"type": "EncounterEnd",
"direct_transition": "Terminal"
},
"Terminal": {
"type": "Terminal"
}
},
"gmf_version": 1
}

View File

@@ -0,0 +1,273 @@
{
"name": "Outgrow Environmental Allergies",
"remarks": [
"When children reach adolescence or early adulthood, especially if they've ",
"undergone immunotherapy, the potential to outgrow environmental allergies ",
"is pretty high. Using the same general 'outgrow' percentage of 75%."
],
"states": {
"Initial": {
"type": "Initial",
"direct_transition": "Tree_Allergy"
},
"Tree_Allergy": {
"type": "Simple",
"remarks": [
"======================================================================",
" OUTGROW TREE ALLERGY ",
"======================================================================"
],
"complex_transition": [
{
"condition": {
"condition_type": "Active Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "419263009",
"display": "Allergy to tree pollen (finding)"
}
]
},
"distributions": [
{
"distribution": 0.75,
"transition": "Outgrow_Tree_Allergy"
},
{
"distribution": 0.25,
"transition": "Grass_Allergy"
}
]
},
{
"distributions": [
{
"distribution": 1,
"transition": "Grass_Allergy"
}
]
}
]
},
"Outgrow_Tree_Allergy": {
"type": "ConditionEnd",
"codes": [
{
"system": "SNOMED-CT",
"code": "419263009",
"display": "Allergy to tree pollen (finding)"
}
],
"direct_transition": "Grass_Allergy"
},
"Grass_Allergy": {
"type": "Simple",
"remarks": [
"======================================================================",
" OUTGROW GRASS ALLERGY ",
"======================================================================"
],
"complex_transition": [
{
"condition": {
"condition_type": "Active Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "418689008",
"display": "Allergy to grass pollen (finding)"
}
]
},
"distributions": [
{
"distribution": 0.75,
"transition": "Outgrow_Grass_Allergy"
},
{
"distribution": 0.25,
"transition": "Mold_Allergy"
}
]
},
{
"distributions": [
{
"distribution": 1,
"transition": "Mold_Allergy"
}
]
}
]
},
"Outgrow_Grass_Allergy": {
"type": "ConditionEnd",
"codes": [
{
"system": "SNOMED-CT",
"code": "418689008",
"display": "Allergy to grass pollen (finding)"
}
],
"direct_transition": "Mold_Allergy"
},
"Mold_Allergy": {
"type": "Simple",
"remarks": [
"======================================================================",
" OUTGROW MOLD ALLERGY ",
"======================================================================"
],
"complex_transition": [
{
"condition": {
"condition_type": "Active Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "419474003",
"display": "Allergy to mold (finding)"
}
]
},
"distributions": [
{
"distribution": 0.75,
"transition": "Outgrow_Mold_Allergy"
},
{
"distribution": 0.25,
"transition": "Pet_Dander_Allergy"
}
]
},
{
"distributions": [
{
"distribution": 1,
"transition": "Pet_Dander_Allergy"
}
]
}
]
},
"Outgrow_Mold_Allergy": {
"type": "ConditionEnd",
"codes": [
{
"system": "SNOMED-CT",
"code": "419474003",
"display": "Allergy to mold (finding)"
}
],
"direct_transition": "Pet_Dander_Allergy"
},
"Pet_Dander_Allergy": {
"type": "Simple",
"remarks": [
"======================================================================",
" OUTGROW PET DANDER ALLERGY ",
"======================================================================"
],
"complex_transition": [
{
"condition": {
"condition_type": "Active Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "717234006",
"display": "Allergy to animal protein (finding)"
}
]
},
"distributions": [
{
"distribution": 0.75,
"transition": "Outgrow_Pet_Dander_Allergy"
},
{
"distribution": 0.25,
"transition": "Mite_Allergy"
}
]
},
{
"distributions": [
{
"distribution": 1,
"transition": "Mite_Allergy"
}
]
}
]
},
"Outgrow_Pet_Dander_Allergy": {
"type": "ConditionEnd",
"codes": [
{
"system": "SNOMED-CT",
"code": "717234006",
"display": "Allergy to animal protein (finding)"
}
],
"direct_transition": "Mite_Allergy"
},
"Mite_Allergy": {
"type": "Simple",
"remarks": [
"======================================================================",
" OUTGROW DUST MITE ALLERGY ",
"======================================================================"
],
"complex_transition": [
{
"condition": {
"condition_type": "Active Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "232350006",
"display": "Allergy to dust mite protein (finding)"
}
]
},
"distributions": [
{
"distribution": 0.75,
"transition": "Outgrow_Mite_Allergy"
},
{
"distribution": 0.25,
"transition": "Terminal"
}
]
},
{
"distributions": [
{
"distribution": 1,
"transition": "Terminal"
}
]
}
]
},
"Outgrow_Mite_Allergy": {
"type": "ConditionEnd",
"codes": [
{
"system": "SNOMED-CT",
"code": "232350006",
"display": "Allergy to dust mite protein (finding)"
}
],
"direct_transition": "Terminal"
},
"Terminal": {
"type": "Terminal"
}
},
"gmf_version": 1
}

View File

@@ -0,0 +1,341 @@
{
"name": "Outgrow Food Allergies",
"remarks": [
"75% of children with food allergies outgrow their sensitivity to ",
"milk, soy, eggs, and wheat. However, allergies to peanuts, tree ",
"nuts, fish, and shellfish are rarely outgrown."
],
"states": {
"Initial": {
"type": "Initial",
"direct_transition": "Wheat_Allergy"
},
"Wheat_Allergy": {
"type": "Simple",
"remarks": [
"======================================================================",
" OUTGROW WHEAT ALLERGY ",
"======================================================================"
],
"complex_transition": [
{
"condition": {
"condition_type": "Active Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "420174000",
"display": "Allergy to wheat (finding)"
}
]
},
"distributions": [
{
"distribution": 0.75,
"transition": "Outgrow_Wheat_Allergy"
},
{
"distribution": 0.25,
"transition": "Dairy_Allergy"
}
]
},
{
"distributions": [
{
"distribution": 1,
"transition": "Dairy_Allergy"
}
]
}
]
},
"Outgrow_Wheat_Allergy": {
"type": "ConditionEnd",
"codes": [
{
"system": "SNOMED-CT",
"code": "420174000",
"display": "Allergy to wheat (finding)"
}
],
"direct_transition": "Dairy_Allergy"
},
"Dairy_Allergy": {
"type": "Simple",
"remarks": [
"======================================================================",
" OUTGROW DAIRY ALLERGY ",
"======================================================================"
],
"complex_transition": [
{
"condition": {
"condition_type": "Active Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "414285001",
"display": "Allergy to food (finding)"
}
]
},
"distributions": [
{
"distribution": 0.75,
"transition": "Outgrow_Dairy_Allergy"
},
{
"distribution": 0.25,
"transition": "Eggs_Allergy"
}
]
},
{
"distributions": [
{
"distribution": 1,
"transition": "Eggs_Allergy"
}
]
}
]
},
"Outgrow_Dairy_Allergy": {
"type": "ConditionEnd",
"codes": [
{
"system": "SNOMED-CT",
"code": "414285001",
"display": "Allergy to food (finding)"
}
],
"direct_transition": "Eggs_Allergy"
},
"Eggs_Allergy": {
"type": "Simple",
"remarks": [
"======================================================================",
" OUTGROW EGGS ALLERGY ",
"======================================================================"
],
"complex_transition": [
{
"condition": {
"condition_type": "Active Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "213020009",
"display": "Allergy to egg protein (finding)"
}
]
},
"distributions": [
{
"distribution": 0.75,
"transition": "Outgrow_Eggs_Allergy"
},
{
"distribution": 0.25,
"transition": "Soy_Allergy"
}
]
},
{
"distributions": [
{
"distribution": 1,
"transition": "Soy_Allergy"
}
]
}
]
},
"Outgrow_Eggs_Allergy": {
"type": "ConditionEnd",
"codes": [
{
"system": "SNOMED-CT",
"code": "213020009",
"display": "Allergy to egg protein (finding)"
}
],
"direct_transition": "Soy_Allergy"
},
"Soy_Allergy": {
"type": "Simple",
"remarks": [
"======================================================================",
" OUTGROW SOY ALLERGY ",
"======================================================================"
],
"complex_transition": [
{
"condition": {
"condition_type": "Active Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "782594005",
"display": "Allergy to soy protein (finding)"
}
]
},
"distributions": [
{
"distribution": 0.75,
"transition": "Outgrow_Soy_Allergy"
},
{
"distribution": 0.25,
"transition": "Latex_Allergy"
}
]
},
{
"distributions": [
{
"distribution": 1,
"transition": "Latex_Allergy"
}
]
}
]
},
"Outgrow_Soy_Allergy": {
"type": "ConditionEnd",
"codes": [
{
"system": "SNOMED-CT",
"code": "782594005",
"display": "Allergy to soy protein (finding)"
}
],
"direct_transition": "Latex_Allergy"
},
"Latex_Allergy": {
"type": "Simple",
"remarks": [
"======================================================================",
" OUTGROW LATEX ALLERGY ",
"======================================================================"
],
"complex_transition": [
{
"condition": {
"condition_type": "Active Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "1003755004",
"display": "Allergy to Hevea brasiliensis latex protein (finding)"
}
]
},
"distributions": [
{
"distribution": 0.75,
"transition": "Outgrow_Latex_Allergy"
},
{
"distribution": 0.25,
"transition": "Check_For_Other_Food_Allergies"
}
]
},
{
"distributions": [
{
"distribution": 1,
"transition": "Check_For_Other_Food_Allergies"
}
]
}
]
},
"Outgrow_Latex_Allergy": {
"type": "ConditionEnd",
"codes": [
{
"system": "SNOMED-CT",
"code": "1003755004",
"display": "Allergy to Hevea brasiliensis latex protein (finding)"
}
],
"direct_transition": "Check_For_Other_Food_Allergies"
},
"Check_For_Other_Food_Allergies": {
"type": "Simple",
"conditional_transition": [
{
"condition": {
"condition_type": "Or",
"conditions": [
{
"condition_type": "Active Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "91935009",
"display": "Allergy to peanut (finding)"
}
]
},
{
"condition_type": "Active Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "91934008",
"display": "Allergy to nut (finding)"
}
]
},
{
"condition_type": "Active Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "417532002",
"display": "Allergy to fish (finding)"
}
]
},
{
"condition_type": "Active Condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "300913006",
"display": "Allergy to shellfish (finding)"
}
]
}
]
},
"transition": "Still_Has_Some_Food_Allergies"
},
{
"transition": "No_Food_Allergies_Here"
}
]
},
"Still_Has_Some_Food_Allergies": {
"type": "SetAttribute",
"attribute": "outgrew_food_allergies",
"value": "false",
"direct_transition": "Terminal"
},
"No_Food_Allergies_Here": {
"type": "SetAttribute",
"attribute": "outgrew_food_allergies",
"value": "true",
"direct_transition": "Terminal"
},
"Terminal": {
"type": "Terminal"
}
},
"gmf_version": 1
}

View File

@@ -0,0 +1,97 @@
{
"name": "Severe Allergic Reaction",
"remarks": [
"A severe allergic reaction is characterized by: ",
"1. A visit to the ED ",
"2. Recording of 'Acute allergic reaction' ",
"3. A dose of adrenaline (epinephrine) to stop the reaction ",
"4. An observation period of 2-6 hours ",
"5. A short prescription for oral steroids, usually prednisone "
],
"states": {
"Initial": {
"type": "Initial",
"direct_transition": "Acute_Allergic_Reaction"
},
"ED_Visit_For_Allergic_Reaction": {
"type": "Encounter",
"encounter_class": "emergency",
"codes": [
{
"system": "SNOMED-CT",
"code": "50849002",
"display": "Emergency room admission (procedure)"
}
],
"direct_transition": "Administer_Epinephrine",
"reason": "Acute_Allergic_Reaction"
},
"Acute_Allergic_Reaction": {
"type": "ConditionOnset",
"target_encounter": "ED_Visit_For_Allergic_Reaction",
"codes": [
{
"system": "SNOMED-CT",
"code": "241929008",
"display": "Acute allergic reaction (disorder)"
}
],
"direct_transition": "ED_Visit_For_Allergic_Reaction"
},
"Administer_Epinephrine": {
"type": "Procedure",
"codes": [
{
"system": "SNOMED-CT",
"code": "313191000",
"display": "Injection of epinephrine (procedure)"
}
],
"direct_transition": "Observation_Period"
},
"Observation_Period": {
"type": "Delay",
"range": {
"low": 2,
"high": 6,
"unit": "hours"
},
"direct_transition": "Mild_Steroid"
},
"Mild_Steroid": {
"type": "MedicationOrder",
"remarks": [
"Typically a mild steroid is given to reduce the chance of the ",
"reaction returning after the adrenaline wears off. Usually this is ",
"just one dose, administered at the hospital."
],
"codes": [
{
"system": "RxNorm",
"code": "312617",
"display": "predniSONE 5 MG Oral Tablet"
}
],
"administration": true,
"direct_transition": "End_Mild_Steroid"
},
"End_Mild_Steroid": {
"type": "MedicationEnd",
"medication_order": "Mild_Steroid",
"direct_transition": "End_Acute_Reaction"
},
"End_Acute_Reaction": {
"type": "ConditionEnd",
"condition_onset": "Acute_Allergic_Reaction",
"direct_transition": "Discharge"
},
"Discharge": {
"type": "EncounterEnd",
"direct_transition": "Terminal"
},
"Terminal": {
"type": "Terminal"
}
},
"gmf_version": 1
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,391 @@
{
"name": "Anemia - Unknown Etiology",
"remarks": [
"A blank module"
],
"states": {
"Initial": {
"type": "Initial",
"conditional_transition": [
{
"transition": "White_Males",
"condition": {
"condition_type": "And",
"conditions": [
{
"condition_type": "Gender",
"gender": "M"
},
{
"condition_type": "Race",
"race": "White"
}
]
}
},
{
"transition": "White_Females",
"condition": {
"condition_type": "And",
"conditions": [
{
"condition_type": "Gender",
"gender": "F"
},
{
"condition_type": "Race",
"race": "White"
}
]
}
},
{
"transition": "Black_Males",
"condition": {
"condition_type": "And",
"conditions": [
{
"condition_type": "Gender",
"gender": "M"
},
{
"condition_type": "Race",
"race": "Black"
}
]
}
},
{
"transition": "Black_Females",
"condition": {
"condition_type": "And",
"conditions": [
{
"condition_type": "Gender",
"gender": "F"
},
{
"condition_type": "Race",
"race": "Black"
}
]
}
},
{
"transition": "Hispanic_Males",
"condition": {
"condition_type": "And",
"conditions": [
{
"condition_type": "Gender",
"gender": "M"
},
{
"condition_type": "Race",
"race": "Hispanic"
}
]
}
},
{
"transition": "Hispanic_Females",
"condition": {
"condition_type": "And",
"conditions": [
{
"condition_type": "Gender",
"gender": "F"
},
{
"condition_type": "Race",
"race": "Hispanic"
}
]
}
}
]
},
"White_Males": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.0031,
"transition": "Delay_0_14"
},
{
"distribution": 0.0031,
"transition": "Delay_15-49"
},
{
"distribution": 0.0215,
"transition": "Delay_50_79"
},
{
"distribution": 0.0209,
"transition": "Delay_80_85"
},
{
"transition": "Terminal",
"distribution": 0.9514
}
]
},
"White_Females": {
"type": "Simple",
"distributed_transition": [
{
"transition": "Delay_0_14",
"distribution": 0.0033
},
{
"distribution": 0.025,
"transition": "Delay_15-49"
},
{
"distribution": 0.0216,
"transition": "Delay_50_79"
},
{
"transition": "Delay_80_85",
"distribution": 0.0142
},
{
"transition": "Terminal",
"distribution": 0.9359
}
]
},
"Black_Males": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.0218,
"transition": "Delay_0_14"
},
{
"distribution": 0.0198,
"transition": "Delay_15-49"
},
{
"transition": "Delay_50_79",
"distribution": 0.0422
},
{
"distribution": 0.0056,
"transition": "Delay_80_85"
},
{
"transition": "Terminal",
"distribution": 0.9106
}
]
},
"Black_Females": {
"type": "Simple",
"distributed_transition": [
{
"transition": "Delay_0_14",
"distribution": 0.0351
},
{
"transition": "Delay_15-49",
"distribution": 0.1309
},
{
"distribution": 0.0586,
"transition": "Delay_50_79"
},
{
"distribution": 0.0093,
"transition": "Delay_80_85"
},
{
"transition": "Terminal",
"distribution": 0.7661
}
]
},
"Hispanic_Males": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.007,
"transition": "Delay_0_14"
},
{
"distribution": 0.003,
"transition": "Delay_15-49"
},
{
"distribution": 0.0124,
"transition": "Delay_50_79"
},
{
"distribution": 0.0024,
"transition": "Delay_80_85"
},
{
"transition": "Terminal",
"distribution": 0.9752
}
]
},
"Hispanic_Females": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.0116,
"transition": "Delay_0_14"
},
{
"distribution": 0.0552,
"transition": "Delay_15-49"
},
{
"distribution": 0.0217,
"transition": "Delay_50_79"
},
{
"distribution": 0.004,
"transition": "Delay_80_85"
},
{
"transition": "Terminal",
"distribution": 0.9075
}
]
},
"Terminal": {
"type": "Terminal"
},
"Fatigue": {
"type": "Symptom",
"symptom": "Fatigue",
"cause": "",
"direct_transition": "Check_Anemia_Exist",
"exact": {
"quantity": 1
}
},
"SOB": {
"type": "Symptom",
"symptom": "Shortness of breath",
"cause": "",
"exact": {
"quantity": 1
},
"direct_transition": "Next_Symptom_2"
},
"Anemia_Submodule": {
"type": "CallSubmodule",
"submodule": "anemia/anemia_sub",
"direct_transition": "Anemia_End"
},
"Delay_0_14": {
"type": "Delay",
"direct_transition": "Anemia_Risk_Group",
"range": {
"low": 0,
"high": 14,
"unit": "years"
}
},
"Delay_15-49": {
"type": "Delay",
"direct_transition": "Anemia_Risk_Group",
"range": {
"low": 15,
"high": 49,
"unit": "years"
}
},
"Delay_50_79": {
"type": "Delay",
"direct_transition": "Anemia_Risk_Group",
"range": {
"low": 50,
"high": 79,
"unit": "years"
}
},
"Delay_80_85": {
"type": "Delay",
"direct_transition": "Anemia_Risk_Group",
"range": {
"low": 80,
"high": 85,
"unit": "years"
}
},
"Tachycardia": {
"type": "Symptom",
"symptom": "Tachycardia",
"cause": "",
"exact": {
"quantity": 1
},
"direct_transition": "Next_Symptom_1"
},
"Anemia_Risk_Group": {
"type": "Simple",
"distributed_transition": [
{
"transition": "Tachycardia",
"distribution": 0.15
},
{
"transition": "Next_Symptom_1",
"distribution": 0.85
}
]
},
"Next_Symptom_1": {
"type": "Simple",
"distributed_transition": [
{
"transition": "SOB",
"distribution": 0.1
},
{
"transition": "Next_Symptom_2",
"distribution": 0.9
}
]
},
"Next_Symptom_2": {
"type": "Simple",
"distributed_transition": [
{
"transition": "Fatigue",
"distribution": 0.15
},
{
"transition": "Check_Anemia_Exist",
"distribution": 0.85
}
]
},
"Check_Anemia_Exist": {
"type": "Simple",
"conditional_transition": [
{
"transition": "Anemia_Submodule",
"condition": {
"condition_type": "Attribute",
"attribute": "anemia",
"operator": "is nil"
}
},
{
"transition": "Terminal"
}
]
},
"Anemia_End": {
"type": "ConditionEnd",
"direct_transition": "Terminal",
"referenced_by_attribute": "anemia"
}
},
"gmf_version": 1
}

View File

@@ -0,0 +1,598 @@
{
"name": "Angina Pectoris",
"remarks": [
"Angina pectoris is a type of chest pain caused by reduced blood flow to the heart muscle.",
"It is a common symptom of coronary artery disease and often described as a feeling of",
"pressure, heaviness, tightness or pain in the chest.",
"Angina can be stable (predictable pain during exertion) or unstable (occurs at rest or worsening pattern).",
"Information on prevalence, risk factors and treatment obtained from:",
"https://www.ncbi.nlm.nih.gov/books/NBK430728/",
"https://www.ahajournals.org/doi/full/10.1161/CIR.0000000000000743"
],
"states": {
"Initial": {
"type": "Initial",
"remarks": [
"======================================================================",
" INCIDENCE ",
"======================================================================",
"Angina affects approximately 3.4% of the US population. The incidence increases with age",
"and is slightly higher in men than women until older ages, when rates equalize.",
"Annual incidence is approximately 0.1-0.2% with higher rates in older populations."
],
"complex_transition": [
{
"condition": {
"condition_type": "Gender",
"gender": "M"
},
"distributions": [
{
"distribution": 0.002,
"transition": "Delay_Until_Angina"
},
{
"distribution": 0.998,
"transition": "Terminal"
}
]
},
{
"condition": {
"condition_type": "Gender",
"gender": "F"
},
"distributions": [
{
"distribution": 0.0015,
"transition": "Delay_Until_Angina"
},
{
"distribution": 0.9985,
"transition": "Terminal"
}
]
}
]
},
"Delay_Until_Angina": {
"type": "Delay",
"range": {
"low": 40,
"high": 85,
"unit": "years"
},
"direct_transition": "Angina_Onset"
},
"Angina_Onset": {
"type": "ConditionOnset",
"target_encounter": "Angina_Diagnosis",
"codes": [
{
"system": "SNOMED-CT",
"code": "194828000",
"display": "Angina pectoris (disorder)"
},
{
"system": "ICD-10-CM",
"code": "I20.9",
"display": "Angina pectoris, unspecified"
}
],
"direct_transition": "Angina_Type_Decision"
},
"Angina_Type_Decision": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.8,
"transition": "Stable_Angina"
},
{
"distribution": 0.2,
"transition": "Unstable_Angina"
}
]
},
"Stable_Angina": {
"type": "ConditionOnset",
"assign_to_attribute": "angina_type",
"codes": [
{
"system": "SNOMED-CT",
"code": "29562005",
"display": "Stable angina (disorder)"
},
{
"system": "ICD-10-CM",
"code": "I20.8",
"display": "Other forms of angina pectoris"
}
],
"direct_transition": "Angina_Symptom_Chest_Pain"
},
"Unstable_Angina": {
"type": "ConditionOnset",
"assign_to_attribute": "angina_type",
"codes": [
{
"system": "SNOMED-CT",
"code": "4557003",
"display": "Preinfarction syndrome (disorder)"
},
{
"system": "ICD-10-CM",
"code": "I20.0",
"display": "Unstable angina"
}
],
"direct_transition": "Angina_Symptom_Chest_Pain"
},
"Angina_Symptom_Chest_Pain": {
"type": "Symptom",
"symptom": "Chest Pain",
"range": {
"low": 40,
"high": 90
},
"direct_transition": "Angina_Symptom_Shortness_of_Breath"
},
"Angina_Symptom_Shortness_of_Breath": {
"type": "Symptom",
"symptom": "Shortness of Breath",
"range": {
"low": 30,
"high": 70
},
"direct_transition": "Angina_Symptom_Fatigue"
},
"Angina_Symptom_Fatigue": {
"type": "Symptom",
"symptom": "Fatigue",
"range": {
"low": 20,
"high": 60
},
"direct_transition": "Angina_Symptom_Nausea"
},
"Angina_Symptom_Nausea": {
"type": "Symptom",
"symptom": "Nausea",
"range": {
"low": 0,
"high": 40
},
"direct_transition": "Angina_Symptom_Sweating"
},
"Angina_Symptom_Sweating": {
"type": "Symptom",
"symptom": "Sweating",
"range": {
"low": 10,
"high": 50
},
"direct_transition": "Angina_Diagnosis"
},
"Angina_Diagnosis": {
"type": "Encounter",
"encounter_class": "ambulatory",
"reason": "Angina_Onset",
"codes": [
{
"system": "SNOMED-CT",
"code": "185345009",
"display": "Encounter for symptom"
}
],
"conditional_transition": [
{
"condition": {
"condition_type": "Attribute",
"attribute": "angina_type",
"operator": "==",
"value": "Unstable_Angina"
},
"transition": "Emergency_Encounter"
},
{
"transition": "Angina_ECG"
}
]
},
"Emergency_Encounter": {
"type": "Encounter",
"encounter_class": "emergency",
"reason": "angina_type",
"codes": [
{
"system": "SNOMED-CT",
"code": "50849002",
"display": "Emergency room admission (procedure)"
}
],
"direct_transition": "Angina_ECG"
},
"Angina_ECG": {
"type": "Procedure",
"reason": "Angina_Onset",
"codes": [
{
"system": "SNOMED-CT",
"code": "29303009",
"display": "Electrocardiographic procedure (procedure)"
}
],
"duration": {
"low": 10,
"high": 15,
"unit": "minutes"
},
"direct_transition": "Angina_Lab_Test"
},
"Angina_Lab_Test": {
"type": "Procedure",
"reason": "Angina_Onset",
"codes": [
{
"system": "SNOMED-CT",
"code": "275907003",
"display": "Cardiac enzyme measurement (procedure)"
}
],
"duration": {
"low": 5,
"high": 10,
"unit": "minutes"
},
"direct_transition": "Angina_Stress_Test_Decision"
},
"Angina_Stress_Test_Decision": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.7,
"transition": "Angina_Stress_Test"
},
{
"distribution": 0.3,
"transition": "Angina_Treatment_Decision"
}
]
},
"Angina_Stress_Test": {
"type": "Procedure",
"reason": "Angina_Onset",
"codes": [
{
"system": "SNOMED-CT",
"code": "13647002",
"display": "Coronary stress test using bicycle ergometer (procedure)"
}
],
"duration": {
"low": 30,
"high": 60,
"unit": "minutes"
},
"direct_transition": "Angina_Treatment_Decision"
},
"Angina_Treatment_Decision": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.85,
"transition": "Angina_Medical_Management"
},
{
"distribution": 0.15,
"transition": "Angina_Advanced_Treatment"
}
]
},
"Angina_Medical_Management": {
"type": "CarePlanStart",
"assign_to_attribute": "angina_careplan",
"reason": "Angina_Onset",
"codes": [
{
"system": "SNOMED-CT",
"code": "395144009",
"display": "Cardiac patient monitoring (regime/therapy)"
}
],
"activities": [
{
"system": "SNOMED-CT",
"code": "229065009",
"display": "Exercise therapy (regime/therapy)"
},
{
"system": "SNOMED-CT",
"code": "226234005",
"display": "Healthy diet (finding)"
},
{
"system": "SNOMED-CT",
"code": "225323000",
"display": "Smoking cessation education (procedure)"
}
],
"direct_transition": "Angina_Medication"
},
"Angina_Medication": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.5,
"transition": "Angina_Nitrates"
},
{
"distribution": 0.3,
"transition": "Angina_Beta_Blockers"
},
{
"distribution": 0.2,
"transition": "Angina_Calcium_Channel_Blockers"
}
]
},
"Angina_Nitrates": {
"type": "MedicationOrder",
"assign_to_attribute": "angina_medication",
"reason": "Angina_Onset",
"codes": [
{
"system": "RxNorm",
"code": "564666",
"display": "Nitroglycerin 0.4 MG/ACTUAT Mucosal Spray"
}
],
"direct_transition": "Angina_Aspirin"
},
"Angina_Beta_Blockers": {
"type": "MedicationOrder",
"assign_to_attribute": "angina_medication",
"reason": "Angina_Onset",
"codes": [
{
"system": "RxNorm",
"code": "197361",
"display": "Atenolol 50 MG Oral Tablet"
}
],
"direct_transition": "Angina_Aspirin"
},
"Angina_Calcium_Channel_Blockers": {
"type": "MedicationOrder",
"assign_to_attribute": "angina_medication",
"reason": "Angina_Onset",
"codes": [
{
"system": "RxNorm",
"code": "835605",
"display": "Amlodipine 5 MG Oral Tablet"
}
],
"direct_transition": "Angina_Aspirin"
},
"Angina_Aspirin": {
"type": "MedicationOrder",
"assign_to_attribute": "angina_aspirin",
"reason": "Angina_Onset",
"codes": [
{
"system": "RxNorm",
"code": "313782",
"display": "Aspirin 81 MG Oral Tablet"
}
],
"direct_transition": "Angina_Statin"
},
"Angina_Statin": {
"type": "MedicationOrder",
"assign_to_attribute": "angina_statin",
"reason": "Angina_Onset",
"codes": [
{
"system": "RxNorm",
"code": "617311",
"display": "Atorvastatin 10 MG Oral Tablet"
}
],
"direct_transition": "End_Diagnosis_Encounter"
},
"Angina_Advanced_Treatment": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.6,
"transition": "Angina_Cardiac_Catheterization"
},
{
"distribution": 0.4,
"transition": "Angina_Coronary_Bypass_Assessment"
}
]
},
"Angina_Cardiac_Catheterization": {
"type": "Procedure",
"reason": "Angina_Onset",
"codes": [
{
"system": "SNOMED-CT",
"code": "80146002",
"display": "Cardiac catheterization (procedure)"
}
],
"duration": {
"low": 1,
"high": 2,
"unit": "hours"
},
"distributed_transition": [
{
"distribution": 0.7,
"transition": "Angina_PCI"
},
{
"distribution": 0.3,
"transition": "Angina_Medical_Management"
}
]
},
"Angina_PCI": {
"type": "Procedure",
"reason": "Angina_Onset",
"codes": [
{
"system": "SNOMED-CT",
"code": "415070008",
"display": "Percutaneous coronary intervention (procedure)"
}
],
"duration": {
"low": 1,
"high": 3,
"unit": "hours"
},
"direct_transition": "Angina_Medical_Management"
},
"Angina_Coronary_Bypass_Assessment": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.6,
"transition": "Angina_CABG"
},
{
"distribution": 0.4,
"transition": "Angina_Medical_Management"
}
]
},
"Angina_CABG": {
"type": "Procedure",
"reason": "Angina_Onset",
"codes": [
{
"system": "SNOMED-CT",
"code": "232717009",
"display": "Coronary artery bypass grafting (procedure)"
}
],
"duration": {
"low": 3,
"high": 5,
"unit": "hours"
},
"direct_transition": "Angina_Medical_Management"
},
"End_Diagnosis_Encounter": {
"type": "EncounterEnd",
"direct_transition": "Followup_Encounter_Delay"
},
"Followup_Encounter_Delay": {
"type": "Delay",
"range": {
"low": 1,
"high": 3,
"unit": "months"
},
"direct_transition": "Angina_Followup"
},
"Angina_Followup": {
"type": "Encounter",
"encounter_class": "ambulatory",
"reason": "Angina_Onset",
"codes": [
{
"system": "SNOMED-CT",
"code": "390906007",
"display": "Follow-up encounter (procedure)"
}
],
"distributed_transition": [
{
"distribution": 0.85,
"transition": "Continue_Angina_Management"
},
{
"distribution": 0.1,
"transition": "Worsen_To_Unstable_Angina"
},
{
"distribution": 0.05,
"transition": "Progress_To_MI"
}
]
},
"Continue_Angina_Management": {
"type": "EncounterEnd",
"direct_transition": "Ongoing_Angina_Care"
},
"Ongoing_Angina_Care": {
"type": "Delay",
"range": {
"low": 4,
"high": 8,
"unit": "months"
},
"direct_transition": "Angina_Followup"
},
"Worsen_To_Unstable_Angina": {
"type": "ConditionEnd",
"condition_onset": "angina_type",
"direct_transition": "Unstable_Angina_Transition"
},
"Unstable_Angina_Transition": {
"type": "Simple",
"conditional_transition": [
{
"condition": {
"condition_type": "Attribute",
"attribute": "angina_type",
"operator": "==",
"value": "Stable_Angina"
},
"transition": "Unstable_Angina"
},
{
"transition": "End_Followup_Encounter"
}
]
},
"Progress_To_MI": {
"type": "ConditionEnd",
"condition_onset": "Angina_Onset",
"direct_transition": "End_Angina_Medications"
},
"End_Angina_Medications": {
"type": "MedicationEnd",
"referenced_by_attribute": "angina_medication",
"direct_transition": "End_Angina_Aspirin"
},
"End_Angina_Aspirin": {
"type": "MedicationEnd",
"referenced_by_attribute": "angina_aspirin",
"direct_transition": "End_Angina_Statin"
},
"End_Angina_Statin": {
"type": "MedicationEnd",
"referenced_by_attribute": "angina_statin",
"direct_transition": "End_Angina_CarePlan"
},
"End_Angina_CarePlan": {
"type": "CarePlanEnd",
"referenced_by_attribute": "angina_careplan",
"direct_transition": "End_Followup_Encounter"
},
"End_Followup_Encounter": {
"type": "EncounterEnd",
"direct_transition": "Terminal"
},
"Terminal": {
"type": "Terminal"
}
},
"gmf_version": 2
}

View File

@@ -0,0 +1,479 @@
{
"name": "Anxiety Disorders",
"gmf_version": 2,
"remarks": [
"Anxiety disorders are the most common mental health disorders in the US, affecting approximately 19.1% of adults annually.",
"Women are more likely to be diagnosed with anxiety disorders than men (lifetime prevalence: 30.5% vs 19.2%).",
"References: https://www.nimh.nih.gov/health/statistics/any-anxiety-disorder",
"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3135672/",
"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4610617/"
],
"states": {
"Initial": {
"type": "Initial",
"conditional_transition": [
{
"condition": {
"condition_type": "Gender",
"gender": "F"
},
"transition": "Female"
},
{
"condition": {
"condition_type": "Gender",
"gender": "M"
},
"transition": "Male"
},
{
"transition": "Terminal"
}
]
},
"Female": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.305,
"transition": "Age_Onset_Determination"
},
{
"distribution": 0.695,
"transition": "Terminal"
}
],
"remarks": [
"Lifetime prevalence of anxiety disorders in women is approximately 30.5%",
"Source: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4610617/"
]
},
"Male": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.192,
"transition": "Age_Onset_Determination"
},
{
"distribution": 0.808,
"transition": "Terminal"
}
],
"remarks": [
"Lifetime prevalence of anxiety disorders in men is approximately 19.2%",
"Source: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4610617/"
]
},
"Age_Onset_Determination": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.25,
"transition": "Childhood_Onset"
},
{
"distribution": 0.45,
"transition": "Young_Adult_Onset"
},
{
"distribution": 0.2,
"transition": "Adult_Onset"
},
{
"distribution": 0.1,
"transition": "Late_Adult_Onset"
}
],
"remarks": [
"Anxiety disorders often begin in childhood, adolescence, or early adulthood",
"Median age of onset is 11 years",
"Source: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3135672/"
]
},
"Childhood_Onset": {
"type": "Delay",
"range": {
"low": 5,
"high": 17,
"unit": "years"
},
"direct_transition": "Anxiety_Symptoms_Begin"
},
"Young_Adult_Onset": {
"type": "Delay",
"range": {
"low": 18,
"high": 30,
"unit": "years"
},
"direct_transition": "Anxiety_Symptoms_Begin"
},
"Adult_Onset": {
"type": "Delay",
"range": {
"low": 31,
"high": 50,
"unit": "years"
},
"direct_transition": "Anxiety_Symptoms_Begin"
},
"Late_Adult_Onset": {
"type": "Delay",
"range": {
"low": 51,
"high": 75,
"unit": "years"
},
"direct_transition": "Anxiety_Symptoms_Begin"
},
"Anxiety_Symptoms_Begin": {
"type": "Symptom",
"symptom": "Excessive Worry",
"range": {
"low": 50,
"high": 100
},
"direct_transition": "Anxiety_Symptom_Restlessness"
},
"Anxiety_Symptom_Restlessness": {
"type": "Symptom",
"symptom": "Restlessness",
"range": {
"low": 40,
"high": 90
},
"direct_transition": "Anxiety_Symptom_Fatigue"
},
"Anxiety_Symptom_Fatigue": {
"type": "Symptom",
"symptom": "Fatigue",
"range": {
"low": 30,
"high": 80
},
"direct_transition": "Anxiety_Symptom_Concentration"
},
"Anxiety_Symptom_Concentration": {
"type": "Symptom",
"symptom": "Difficulty Concentrating",
"range": {
"low": 30,
"high": 80
},
"direct_transition": "Anxiety_Symptom_Irritability"
},
"Anxiety_Symptom_Irritability": {
"type": "Symptom",
"symptom": "Irritability",
"range": {
"low": 40,
"high": 90
},
"direct_transition": "Anxiety_Symptom_Muscle_Tension"
},
"Anxiety_Symptom_Muscle_Tension": {
"type": "Symptom",
"symptom": "Muscle Tension",
"range": {
"low": 30,
"high": 80
},
"direct_transition": "Anxiety_Symptom_Sleep_Problems"
},
"Anxiety_Symptom_Sleep_Problems": {
"type": "Symptom",
"symptom": "Sleep Problems",
"range": {
"low": 40,
"high": 90
},
"direct_transition": "Symptom_Period"
},
"Symptom_Period": {
"type": "Delay",
"range": {
"low": 2,
"high": 8,
"unit": "weeks"
},
"direct_transition": "Seek_Care_Decision"
},
"Seek_Care_Decision": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.6,
"transition": "Anxiety_Disorder_Diagnosis"
},
{
"distribution": 0.4,
"transition": "Untreated_Anxiety"
}
],
"remarks": [
"Only about 60% of people with anxiety disorders seek treatment",
"Source: https://www.nimh.nih.gov/health/statistics/any-anxiety-disorder"
]
},
"Untreated_Anxiety": {
"type": "Delay",
"range": {
"low": 1,
"high": 10,
"unit": "years"
},
"distributed_transition": [
{
"distribution": 0.3,
"transition": "Anxiety_Disorder_Diagnosis"
},
{
"distribution": 0.7,
"transition": "Living_With_Untreated_Anxiety"
}
],
"remarks": [
"Some patients may eventually seek care after prolonged symptoms"
]
},
"Living_With_Untreated_Anxiety": {
"type": "Simple",
"direct_transition": "Terminal"
},
"Anxiety_Disorder_Diagnosis": {
"type": "Encounter",
"encounter_class": "ambulatory",
"reason": "Excessive Worry",
"codes": [
{
"system": "SNOMED-CT",
"code": "185347001",
"display": "Encounter for problem (procedure)"
}
],
"direct_transition": "Anxiety_Disorder_Onset"
},
"Anxiety_Disorder_Onset": {
"type": "ConditionOnset",
"target_encounter": "Anxiety_Disorder_Diagnosis",
"assign_to_attribute": "anxiety_disorder",
"codes": [
{
"system": "SNOMED-CT",
"code": "197480006",
"display": "Anxiety disorder (disorder)"
},
{
"system": "ICD-10-CM",
"code": "F41.9",
"display": "Anxiety disorder, unspecified"
}
],
"direct_transition": "Anxiety_Screening"
},
"Anxiety_Screening": {
"type": "Procedure",
"target_encounter": "Anxiety_Disorder_Diagnosis",
"reason": "anxiety_disorder",
"codes": [
{
"system": "LOINC",
"code": "70274-6",
"display": "Generalized anxiety disorder 7 item (GAD-7) total score [Reported]"
}
],
"direct_transition": "Treatment_Decision"
},
"Treatment_Decision": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.5,
"transition": "Medication_Treatment"
},
{
"distribution": 0.3,
"transition": "Therapy_Treatment"
},
{
"distribution": 0.2,
"transition": "Combined_Treatment"
}
],
"remarks": [
"Treatment approaches vary based on severity, patient preference, and provider recommendation"
]
},
"Medication_Treatment": {
"type": "MedicationOrder",
"target_encounter": "Anxiety_Disorder_Diagnosis",
"reason": "anxiety_disorder",
"codes": [
{
"system": "RxNorm",
"code": "866924",
"display": "Sertraline 50 MG Oral Tablet"
}
],
"direct_transition": "Follow_Up_Encounter"
},
"Therapy_Treatment": {
"type": "Procedure",
"target_encounter": "Anxiety_Disorder_Diagnosis",
"reason": "anxiety_disorder",
"codes": [
{
"system": "SNOMED-CT",
"code": "304891004",
"display": "Cognitive behavioral therapy (procedure)"
}
],
"direct_transition": "Follow_Up_Encounter"
},
"Combined_Treatment": {
"type": "MedicationOrder",
"target_encounter": "Anxiety_Disorder_Diagnosis",
"reason": "anxiety_disorder",
"codes": [
{
"system": "RxNorm",
"code": "866924",
"display": "Sertraline 50 MG Oral Tablet"
}
],
"direct_transition": "Add_Therapy"
},
"Add_Therapy": {
"type": "Procedure",
"target_encounter": "Anxiety_Disorder_Diagnosis",
"reason": "anxiety_disorder",
"codes": [
{
"system": "SNOMED-CT",
"code": "304891004",
"display": "Cognitive behavioral therapy (procedure)"
}
],
"direct_transition": "Follow_Up_Encounter"
},
"Follow_Up_Encounter": {
"type": "Encounter",
"encounter_class": "ambulatory",
"reason": "anxiety_disorder",
"codes": [
{
"system": "SNOMED-CT",
"code": "390906007",
"display": "Follow-up encounter (procedure)"
}
],
"direct_transition": "End_Initial_Encounter"
},
"End_Initial_Encounter": {
"type": "EncounterEnd",
"direct_transition": "Anxiety_Symptom_Improvement"
},
"Anxiety_Symptom_Improvement": {
"type": "Delay",
"range": {
"low": 4,
"high": 12,
"unit": "weeks"
},
"direct_transition": "Reduce_Excessive_Worry"
},
"Reduce_Excessive_Worry": {
"type": "Symptom",
"symptom": "Excessive Worry",
"range": {
"low": 10,
"high": 50
},
"direct_transition": "Reduce_Restlessness"
},
"Reduce_Restlessness": {
"type": "Symptom",
"symptom": "Restlessness",
"range": {
"low": 10,
"high": 40
},
"direct_transition": "Reduce_Fatigue"
},
"Reduce_Fatigue": {
"type": "Symptom",
"symptom": "Fatigue",
"range": {
"low": 10,
"high": 40
},
"direct_transition": "Reduce_Concentration_Issues"
},
"Reduce_Concentration_Issues": {
"type": "Symptom",
"symptom": "Difficulty Concentrating",
"range": {
"low": 10,
"high": 40
},
"direct_transition": "Reduce_Irritability"
},
"Reduce_Irritability": {
"type": "Symptom",
"symptom": "Irritability",
"range": {
"low": 10,
"high": 40
},
"direct_transition": "Reduce_Muscle_Tension"
},
"Reduce_Muscle_Tension": {
"type": "Symptom",
"symptom": "Muscle Tension",
"range": {
"low": 10,
"high": 40
},
"direct_transition": "Reduce_Sleep_Problems"
},
"Reduce_Sleep_Problems": {
"type": "Symptom",
"symptom": "Sleep Problems",
"range": {
"low": 10,
"high": 40
},
"direct_transition": "Ongoing_Care"
},
"Ongoing_Care": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.7,
"transition": "Maintenance_Phase"
},
{
"distribution": 0.2,
"transition": "Relapse"
},
{
"distribution": 0.1,
"transition": "Remission"
}
],
"remarks": [
"Most patients require ongoing treatment, some experience relapse, and a small percentage achieve full remission"
]
},
"Maintenance_Phase": {
"type": "Delay",
"range": {
"low": 6,
"high": 24,
"unit": "months"
},
"direct_transition": "Maintenance_Encounter"
}
}
}

View File

@@ -0,0 +1,402 @@
{
"name": "Appendicitis",
"states": {
"Initial": {
"type": "Initial",
"conditional_transition": [
{
"condition": {
"condition_type": "Gender",
"gender": "M"
},
"transition": "Male"
},
{
"condition": {
"condition_type": "Gender",
"gender": "F"
},
"transition": "Female"
},
{
"transition": "Terminal"
}
]
},
"Male": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.086,
"transition": "Pre_appendicitis"
},
{
"distribution": 0.914,
"transition": "Terminal"
}
],
"remarks": [
"Men have an approx lifetime risk of appendicitis of 8.6%. Ref: http://www.ncbi.nlm.nih.gov/pubmed/2239906"
]
},
"Female": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.067,
"transition": "Pre_appendicitis"
},
{
"distribution": 0.933,
"transition": "Terminal"
}
],
"remarks": [
"Women have an approx lifetime risk of appendicitis of 6.7%. Ref: http://www.ncbi.nlm.nih.gov/pubmed/2239906"
]
},
"Pre_appendicitis": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.263,
"transition": "Ages_1_17"
},
{
"distribution": 0.423,
"transition": "Ages_18_44"
},
{
"distribution": 0.221,
"transition": "Ages_45_64"
},
{
"distribution": 0.093,
"transition": "Ages_65_Plus"
}
],
"remarks": [
"Age distribution of appendicitis from https://www.ncbi.nlm.nih.gov/books/NBK169006/ , Table 1"
]
},
"Ages_1_17": {
"type": "Delay",
"range": {
"low": 1,
"high": 17,
"unit": "years"
},
"direct_transition": "Appendicitis_Symptom1"
},
"Ages_18_44": {
"type": "Delay",
"range": {
"low": 18,
"high": 44,
"unit": "years"
},
"direct_transition": "Appendicitis_Symptom1"
},
"Ages_45_64": {
"type": "Delay",
"range": {
"low": 45,
"high": 64,
"unit": "years"
},
"direct_transition": "Appendicitis_Symptom1"
},
"Ages_65_Plus": {
"type": "Delay",
"range": {
"low": 65,
"high": 99,
"unit": "years"
},
"direct_transition": "Appendicitis_Symptom1"
},
"Appendicitis_Symptom1": {
"type": "Symptom",
"symptom": "Abdominal Pain",
"range": {
"low": 50,
"high": 150
},
"direct_transition": "Appendicitis_Symptom2"
},
"Appendicitis_Symptom2": {
"type": "Symptom",
"symptom": "Fever",
"range": {
"low": 50,
"high": 100
},
"direct_transition": "Appendicitis_Symptom3"
},
"Appendicitis_Symptom3": {
"type": "Symptom",
"symptom": "Loss of Appetite",
"range": {
"low": 50,
"high": 100
},
"direct_transition": "Appendicitis_Symptom4"
},
"Appendicitis_Symptom4": {
"type": "Symptom",
"symptom": "Nausea/Vomiting",
"range": {
"low": 0,
"high": 50
},
"direct_transition": "Appendicitis_Symptom5"
},
"Appendicitis_Symptom5": {
"type": "Symptom",
"symptom": "Diarrhea",
"range": {
"low": 0,
"high": 50
},
"direct_transition": "Appendicitis_Symptom6"
},
"Appendicitis_Symptom6": {
"type": "Symptom",
"symptom": "Bloating/Gas",
"range": {
"low": 0,
"high": 50
},
"direct_transition": "Appendicitis_Symptom7"
},
"Appendicitis_Symptom7": {
"type": "Symptom",
"symptom": "Constipation",
"range": {
"low": 0,
"high": 50
},
"direct_transition": "Symptom_Period"
},
"Symptom_Period": {
"type": "Delay",
"range": {
"low": 1,
"high": 3,
"unit": "days"
},
"direct_transition": "Appendicitis"
},
"Appendicitis": {
"type": "ConditionOnset",
"target_encounter": "Appendicitis_Encounter",
"codes": [
{
"system": "SNOMED-CT",
"code": "74400008",
"display": "Appendicitis (disorder)"
}
],
"distributed_transition": [
{
"distribution": 0.7,
"transition": "Appendicitis_Encounter"
},
{
"distribution": 0.3,
"transition": "Rupture"
}
],
"remarks": [
"The rate of perforation varies from 16% to 40%, with a higher frequency occurring in younger age groups (40-57%)",
"and in patients older than 50 years (55-70%), in whom misdiagnosis and delayed diagnosis are common.",
"(ref: http://emedicine.medscape.com/article/773895-overview#a7 )",
"From table 1 here: https://www.ncbi.nlm.nih.gov/books/NBK169006/ it's about 30%",
"For simplicity here I just round to 30% for all age groups."
]
},
"Rupture": {
"type": "ConditionOnset",
"target_encounter": "Appendicitis_Encounter",
"codes": [
{
"system": "SNOMED-CT",
"code": "47693006",
"display": "Rupture of appendix (disorder)"
}
],
"direct_transition": "Appendicitis_Encounter"
},
"Appendicitis_Encounter": {
"type": "Encounter",
"encounter_class": "emergency",
"reason": "Appendicitis",
"remarks": [
"Currently the GMF does not include Vital Signs, if we decide to add that then there are some lab tests we could add at this Encounter."
],
"codes": [
{
"system": "SNOMED-CT",
"code": "50849002",
"display": "Emergency room admission (procedure)"
}
],
"direct_transition": "History_of_Appendectomy"
},
"History_of_Appendectomy": {
"type": "ConditionOnset",
"target_encounter": "Appendectomy_Encounter",
"codes": [
{
"system": "SNOMED-CT",
"code": "428251008",
"display": "History of appendectomy (situation)"
}
],
"direct_transition": "Transfer_To_Inpatient"
},
"Appendectomy_Encounter": {
"type": "Encounter",
"encounter_class": "inpatient",
"reason": "Appendicitis",
"codes": [
{
"system": "SNOMED-CT",
"code": "185347001",
"display": "Encounter for problem (procedure)"
}
],
"direct_transition": "Appendectomy"
},
"Appendectomy": {
"type": "Procedure",
"reason": "Appendicitis",
"codes": [
{
"system": "SNOMED-CT",
"code": "80146002",
"display": "Excision of appendix (procedure)"
}
],
"duration": {
"low": 40,
"high": 70,
"unit": "minutes"
},
"remarks": [
"Avg operative time is ~55 minutes",
"https://www.ncbi.nlm.nih.gov/pubmed/17658102"
],
"direct_transition": "End_Appendicitis"
},
"Appendicitis_Symptom1_Ends": {
"type": "Symptom",
"symptom": "Abdominal Pain",
"exact": {
"quantity": 0
},
"direct_transition": "Appendicitis_Symptom2_Ends"
},
"Appendicitis_Symptom2_Ends": {
"type": "Symptom",
"symptom": "Fever",
"exact": {
"quantity": 0
},
"direct_transition": "Appendicitis_Symptom3_Ends"
},
"Appendicitis_Symptom3_Ends": {
"type": "Symptom",
"symptom": "Loss of Appetite",
"exact": {
"quantity": 0
},
"direct_transition": "Appendicitis_Symptom4_Ends"
},
"Appendicitis_Symptom4_Ends": {
"type": "Symptom",
"symptom": "Nausea/Vomiting",
"exact": {
"quantity": 0
},
"direct_transition": "Appendicitis_Symptom5_Ends"
},
"Appendicitis_Symptom5_Ends": {
"type": "Symptom",
"symptom": "Diarrhea",
"exact": {
"quantity": 0
},
"direct_transition": "Appendicitis_Symptom6_Ends"
},
"Appendicitis_Symptom6_Ends": {
"type": "Symptom",
"symptom": "Bloating/Gas",
"exact": {
"quantity": 0
},
"direct_transition": "Appendicitis_Symptom7_Ends"
},
"Appendicitis_Symptom7_Ends": {
"type": "Symptom",
"symptom": "Constipation",
"exact": {
"quantity": 0
},
"direct_transition": "Recovery"
},
"Recovery": {
"type": "Delay",
"range": {
"low": 1,
"high": 5,
"unit": "days"
},
"remarks": [
"Traditionally, patients are hospitalized for 24 hours after laparoscopic appendectomy. ",
"A retrospective review of 119 patients [...] ",
"Forty-two patients were dismissed on the day of surgery and 77 were admitted for 1 to 5 days postoperatively.",
"https://www.ncbi.nlm.nih.gov/pubmed/22369831"
],
"direct_transition": "End_Appendectomy_Encounter"
},
"End_Appendectomy_Encounter": {
"type": "EncounterEnd",
"discharge_disposition": {
"system": "NUBC",
"code": "01",
"display": "Discharged to home care or self care (routine discharge)"
},
"direct_transition": "Terminal"
},
"Terminal": {
"type": "Terminal"
},
"Transfer_To_Inpatient": {
"type": "EncounterEnd",
"direct_transition": "Appendectomy_Encounter"
},
"End_Appendicitis": {
"type": "ConditionEnd",
"condition_onset": "Appendicitis",
"conditional_transition": [
{
"transition": "End_Rupture",
"condition": {
"condition_type": "PriorState",
"name": "Rupture"
}
},
{
"transition": "Appendicitis_Symptom1_Ends"
}
]
},
"End_Rupture": {
"type": "ConditionEnd",
"direct_transition": "Appendicitis_Symptom1_Ends",
"condition_onset": "Rupture"
}
},
"gmf_version": 1
}

View File

@@ -0,0 +1,593 @@
{
"name": "Asthma",
"remarks": [
"This module is mostly based on statistics from the AAAAI and CDC. See:",
"http://www.aaaai.org/about-aaaai/newsroom/asthma-statistics",
"http://www.cdc.gov/nchs/fastats/asthma.htm",
"http://www.cdc.gov/nchs/products/databriefs/db94.htm"
],
"states": {
"Initial": {
"type": "Initial",
"direct_transition": "Delay_For_Atopy"
},
"Delay_For_Atopy": {
"type": "Delay",
"remarks": [
"The Atopy module must be processed before any of the allergy modules so ",
"atopy can appropriately influence allergies. Delaying the smallest possible ",
"time step to ensure this happens."
],
"exact": {
"quantity": 1,
"unit": "weeks"
},
"conditional_transition": [
{
"condition": {
"condition_type": "Attribute",
"attribute": "atopic",
"operator": "is not nil"
},
"transition": "Atopic"
},
{
"transition": "Not_Atopic"
}
]
},
"Atopic": {
"type": "Simple",
"remarks": [
"45% of all atopic patients develop asthma. See the Atopy model for more info."
],
"distributed_transition": [
{
"distribution": 0.45,
"transition": "Asthma_Incidence"
},
{
"distribution": 0.55,
"transition": "Terminal"
}
]
},
"Not_Atopic": {
"type": "Simple",
"remarks": [
"There is a possibility that non-atopic patients develop asthma. However, ",
"this asthma is likely more environmental and more likely to develop in ",
"adulthood. Overall, 8-9% of the population gets asthma. In this model 6.8% ",
"of those patients are atopic. The remaining 1.2-2% are not."
],
"distributed_transition": [
{
"distribution": 0.023,
"transition": "Asthma_Incidence"
},
{
"distribution": 0.977,
"transition": "Terminal"
}
]
},
"Asthma_Incidence": {
"type": "Simple",
"remarks": [
"8.6% of children have asthma, 7.4% of adults. To model childhood-only, lifetime, and adult-onset",
"asthma I try to distribute the patients in a reasonable (but slightly arbitrary) manner:",
" ,-> 1.6% childhood-only ",
" birth --> 7.0% lifetime = 8.6% childhood asthma",
" `-> 0.4% adult-onset = 7.4% adult asthma ",
"Collectively this sums to 9% of people getting asthma in their lifetime, which is consistent with",
"my extrapolation based on the AAAAI's estimates: (1/14 had asthma in 2001, 1/12 in 2009, so I extrapolate",
"1/11 for 2016)."
],
"distributed_transition": [
{
"distribution": 0.95,
"transition": "Delay_For_Childhood_Asthma"
},
{
"distribution": 0.05,
"transition": "Delay_Until_Adulthood"
}
]
},
"Delay_For_Childhood_Asthma": {
"type": "Delay",
"remarks": [
"Typically asthma symptoms don't appear until the child is at least 3."
],
"range": {
"low": 2,
"high": 5,
"unit": "years"
},
"direct_transition": "Childhood_Asthma_Begins"
},
"Delay_Until_Adulthood": {
"type": "Delay",
"range": {
"low": 18,
"high": 40,
"unit": "years"
},
"direct_transition": "Adult_Asthma_Begins"
},
"Childhood_Asthma_Begins": {
"type": "ConditionOnset",
"target_encounter": "Asthma_Diagnosis",
"assign_to_attribute": "asthma_condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "233678006",
"display": "Childhood asthma (disorder)"
}
],
"direct_transition": "Set_Childhood_Asthma"
},
"Set_Childhood_Asthma": {
"type": "SetAttribute",
"attribute": "asthma_type",
"value": "childhood",
"direct_transition": "Asthma_Diagnosis"
},
"Adult_Asthma_Begins": {
"type": "ConditionOnset",
"target_encounter": "Asthma_Diagnosis",
"assign_to_attribute": "asthma_condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "195967001",
"display": "Asthma (disorder)"
}
],
"direct_transition": "Set_Adult_Asthma"
},
"Set_Adult_Asthma": {
"type": "SetAttribute",
"attribute": "asthma_type",
"value": "lifelong",
"direct_transition": "Asthma_Diagnosis"
},
"Asthma_Diagnosis": {
"type": "Encounter",
"encounter_class": "ambulatory",
"reason": "asthma_condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "185345009",
"display": "Encounter for symptom (procedure)"
}
],
"direct_transition": "Asthma_Symptom1"
},
"Asthma_Symptom1": {
"type": "Symptom",
"symptom": "Wheezing",
"range": {
"low": 25,
"high": 75
},
"direct_transition": "Asthma_Symptom2"
},
"Asthma_Symptom2": {
"type": "Symptom",
"symptom": "Shortness of Breath",
"range": {
"low": 25,
"high": 75
},
"direct_transition": "Asthma_Symptom3"
},
"Asthma_Symptom3": {
"type": "Symptom",
"symptom": "Chest Pressure",
"range": {
"low": 0,
"high": 50
},
"direct_transition": "Asthma_Symptom4"
},
"Asthma_Symptom4": {
"type": "Symptom",
"symptom": "Cough",
"range": {
"low": 0,
"high": 25
},
"direct_transition": "Asthma_Symptom5"
},
"Asthma_Symptom5": {
"type": "Symptom",
"symptom": "Nasal Congestion",
"range": {
"low": 0,
"high": 25
},
"direct_transition": "Asthma_Symptom6"
},
"Asthma_Symptom6": {
"type": "Symptom",
"symptom": "Mucus Secretion",
"range": {
"low": 0,
"high": 25
},
"direct_transition": "Asthma_Screening"
},
"Asthma_Screening": {
"type": "Procedure",
"reason": "asthma_condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "171231001",
"display": "Asthma screening (procedure)"
}
],
"direct_transition": "Prescribe_Maintenance_Inhaler"
},
"Prescribe_Maintenance_Inhaler": {
"type": "CallSubmodule",
"submodule": "medications/maintenance_inhaler",
"direct_transition": "Prescribe_Emergency_Inhaler"
},
"Prescribe_Emergency_Inhaler": {
"type": "CallSubmodule",
"submodule": "medications/emergency_inhaler",
"direct_transition": "Asthma_CarePlan_Selector"
},
"Asthma_CarePlan_Selector": {
"type": "Simple",
"conditional_transition": [
{
"condition": {
"condition_type": "And",
"conditions": [
{
"condition_type": "Age",
"operator": ">=",
"quantity": 18,
"unit": "years"
},
{
"condition_type": "Attribute",
"attribute": "smoker",
"operator": "==",
"value": true
}
]
},
"transition": "Smoker_CarePlan"
},
{
"transition": "Nonsmoker_CarePlan"
}
]
},
"Smoker_CarePlan": {
"type": "CarePlanStart",
"assign_to_attribute": "asthma_careplan",
"reason": "asthma_condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "699728000",
"display": "Asthma self management (regime/therapy)"
}
],
"activities": [
{
"system": "SNOMED-CT",
"code": "710081004",
"display": "Smoking cessation therapy (regime/therapy)"
},
{
"system": "SNOMED-CT",
"code": "710818004",
"display": "Inhaled steroid therapy (procedure)"
},
{
"system": "SNOMED-CT",
"code": "708409001",
"display": "Home nebulizer therapy (procedure)"
}
],
"direct_transition": "End_Diagnosis_Encounter"
},
"Nonsmoker_CarePlan": {
"type": "CarePlanStart",
"assign_to_attribute": "asthma_careplan",
"reason": "asthma_condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "699728000",
"display": "Asthma self management (regime/therapy)"
}
],
"activities": [
{
"system": "SNOMED-CT",
"code": "710818004",
"display": "Inhaled steroid therapy (procedure)"
},
{
"system": "SNOMED-CT",
"code": "708409001",
"display": "Home nebulizer therapy (procedure)"
},
{
"system": "SNOMED-CT",
"code": "229298005",
"display": "Breathing control (regime/therapy)"
}
],
"direct_transition": "End_Diagnosis_Encounter"
},
"End_Diagnosis_Encounter": {
"type": "EncounterEnd",
"direct_transition": "Maintaining_Asthma"
},
"Maintaining_Asthma": {
"type": "Delay",
"exact": {
"quantity": 6,
"unit": "months"
},
"conditional_transition": [
{
"condition": {
"remarks": [
"Childhood-only asthma ends"
],
"condition_type": "And",
"conditions": [
{
"condition_type": "Age",
"operator": ">",
"quantity": 18,
"unit": "years"
},
{
"condition_type": "Attribute",
"attribute": "asthma_type",
"operator": "==",
"value": "childhood"
}
]
},
"transition": "Childhood_Asthma_May_Subside"
},
{
"transition": "Potential_Asthma_Attack"
}
]
},
"Childhood_Asthma_May_Subside": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.83,
"transition": "Childhood_Asthma_Becomes_Lifelong_Asthma"
},
{
"distribution": 0.17,
"transition": "Next_Wellness_Encounter"
}
],
"remarks": [
"After a validation study, 248 children were identified as having asthma; these children were reassessed annually until age 19 years when 205 (83%) remained.",
"\"Remission and persistence of asthma followed from 7 to 19 years of age.\" Andersson M, Hedman L, Bjerg A, Forsberg B, Lundbäck B, Rönmark E. Pediatrics. 2013 Aug;132(2):e435-42. doi: 10.1542/peds.2013-0741.",
"https://www.ncbi.nlm.nih.gov/pubmed/23897917"
]
},
"Childhood_Asthma_Becomes_Lifelong_Asthma": {
"type": "ConditionEnd",
"referenced_by_attribute": "asthma_condition",
"direct_transition": "Lifelong_Asthma"
},
"Lifelong_Asthma": {
"type": "SetAttribute",
"attribute": "asthma_type",
"value": "lifelong",
"direct_transition": "Next_Adult_Welness_Encounter"
},
"Next_Adult_Welness_Encounter": {
"type": "Encounter",
"wellness": true,
"direct_transition": "Lifelong_Asthma_Begins",
"reason": "asthma_condition"
},
"Lifelong_Asthma_Begins": {
"type": "ConditionOnset",
"target_encounter": "Next_Adult_Welness_Encounter",
"assign_to_attribute": "asthma_condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "195967001",
"display": "Asthma (disorder)"
}
],
"direct_transition": "End_Wellness_1"
},
"Potential_Asthma_Attack": {
"type": "Simple",
"remarks": [
"Once every 6 months we simulate whether or not the patient has an asthma attack",
"53% have an attack each year (57% children, 51% adults), source: AAAAI.",
"This means a 26.5% rate of attack per 6 month period."
],
"distributed_transition": [
{
"distribution": 0.735,
"transition": "Maintaining_Asthma",
"remarks": [
"No asthma attack occured"
]
},
{
"distribution": 0.265,
"transition": "Asthma_Attack"
}
]
},
"Asthma_Attack": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.1885,
"transition": "Asthma_ED_Visit",
"remarks": [
"The CDC documented 10 ED visits per 100 people with asthma each year.",
"http://www.cdc.gov/nchs/products/databriefs/db94.htm",
"Assuming hospitalization always comes from an attack, for those that have attacks each 6-month period (26.5%)",
"5/26.5 people (per 100) --> 18.85% rate of hospitalization from attack."
]
},
{
"distribution": 0.8115,
"transition": "Asthma_Attack_Followup",
"remarks": [
"If the attack did not result in an ED visit the patient still visited his/her physician for a followup"
]
}
]
},
"Asthma_ED_Visit": {
"type": "Encounter",
"encounter_class": "emergency",
"reason": "asthma_condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "183478001",
"display": "Emergency hospital admission for asthma (procedure)"
}
],
"direct_transition": "End_Asthma_ED_Visit"
},
"End_Asthma_ED_Visit": {
"type": "EncounterEnd",
"direct_transition": "Delay_For_Followup"
},
"Delay_For_Followup": {
"type": "Delay",
"range": {
"low": 1,
"high": 3,
"unit": "days"
},
"direct_transition": "Asthma_Attack_Followup"
},
"Asthma_Attack_Followup": {
"type": "Encounter",
"encounter_class": "ambulatory",
"reason": "asthma_condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "394701000",
"display": "Asthma follow-up (regime/therapy)"
}
],
"direct_transition": "Followup_End"
},
"Followup_End": {
"type": "EncounterEnd",
"direct_transition": "Maintaining_Asthma"
},
"Next_Wellness_Encounter": {
"type": "Encounter",
"wellness": true,
"direct_transition": "Maintenance_Medication_End",
"reason": "asthma_condition"
},
"Maintenance_Medication_End": {
"type": "MedicationEnd",
"referenced_by_attribute": "maintenance_inhaler",
"direct_transition": "Emergency_Medication_End"
},
"Emergency_Medication_End": {
"type": "MedicationEnd",
"referenced_by_attribute": "emergency_inhaler",
"direct_transition": "Childhood_Asthma_Subsides"
},
"Childhood_Asthma_Subsides": {
"type": "ConditionEnd",
"referenced_by_attribute": "asthma_condition",
"direct_transition": "Asthma_Symptom1_Ends"
},
"Asthma_Symptom1_Ends": {
"type": "Symptom",
"symptom": "Wheezing",
"exact": {
"quantity": 0
},
"direct_transition": "Asthma_Symptom2_Ends"
},
"Asthma_Symptom2_Ends": {
"type": "Symptom",
"symptom": "Shortness of Breath",
"exact": {
"quantity": 0
},
"direct_transition": "Asthma_Symptom3_Ends"
},
"Asthma_Symptom3_Ends": {
"type": "Symptom",
"symptom": "Chest Pressure",
"exact": {
"quantity": 0
},
"direct_transition": "Asthma_Symptom4_Ends"
},
"Asthma_Symptom4_Ends": {
"type": "Symptom",
"symptom": "Cough",
"exact": {
"quantity": 0
},
"direct_transition": "Asthma_Symptom5_Ends"
},
"Asthma_Symptom5_Ends": {
"type": "Symptom",
"symptom": "Nasal Congestion",
"exact": {
"quantity": 0
},
"direct_transition": "Asthma_Symptom6_Ends"
},
"Asthma_Symptom6_Ends": {
"type": "Symptom",
"symptom": "Mucus Secretion",
"exact": {
"quantity": 0
},
"direct_transition": "End_Asthma_CarePlan"
},
"End_Asthma_CarePlan": {
"type": "CarePlanEnd",
"referenced_by_attribute": "asthma_careplan",
"direct_transition": "End_Wellness_2"
},
"Terminal": {
"type": "Terminal"
},
"End_Wellness_1": {
"type": "EncounterEnd",
"direct_transition": "Maintaining_Asthma"
},
"End_Wellness_2": {
"type": "EncounterEnd",
"direct_transition": "Terminal"
}
},
"gmf_version": 1
}

View File

@@ -0,0 +1,196 @@
{
"name": "Atopy",
"remarks": [
"'Atopy' specifically refers to the genetic tendency to develop allergic diseases.",
"https://www.aaaai.org/conditions-and-treatments/conditions-dictionary/atopy",
"Atopy is the most significant factor in the 'atopic triad' of: ",
"1. Atopic Dermatitis (Eczema) ",
"2. Asthma ",
"3. Environmental and Food Allergies ",
"4. Allergic Rhinitis (Hay Fever) ",
"Okay... so maybe the atopic triad could be a 'quartet'.",
"Up to 20% of children display signs of atopy, 50% by age 1 and 95% by age 5.",
"75% of children with atopic symptoms outgrow them by adolescence or early ",
"adulthood. However, 25% show symptoms for life. It is of course possible to be ",
"non-atopic and still develop allergies and asthma.",
"The prevalence of atopy and allergies has increased substantially in the 20th ",
"century, especially after the 1960's, typically at a rate of 0.15 - 0.3% per ",
"year. To model this historical increase in allergy prevalence atopy is the driving ",
"factor. In this model the incidence of atopy increases at 1.875% per decade, or about ",
"0.19% per year since 1940.",
"Source: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4629767/",
"There is a complex relationship between allergies, asthma, and eczema.",
"In a word, those with atopy have a significantly increased risk of severe ",
"and moderate allergies.",
"The final model: ",
" Total ,--> 85% Allergic Rhinitis (12.8% overall)",
" Population ---> 15% ATOPIC ---> 55% Atopic Dermatitis (8.25% overall)",
" |`--> 45% Asthma (6.75% overall)",
" `---> 25% Food & Environmental Allergies (3.75% overall)",
"Above, 15% of all people are atopic by 2010."
],
"states": {
"Initial": {
"type": "Initial",
"complex_transition": [
{
"condition": {
"condition_type": "Date",
"operator": "<",
"year": 1940
},
"distributions": [
{
"distribution": 1,
"transition": "Terminal"
}
]
},
{
"condition": {
"condition_type": "Date",
"operator": "<",
"year": 1950
},
"distributions": [
{
"distribution": 0.01875,
"transition": "Is_Atopic"
},
{
"distribution": 0.98125,
"transition": "Terminal"
}
]
},
{
"condition": {
"condition_type": "Date",
"operator": "<",
"year": 1960
},
"distributions": [
{
"distribution": 0.0375,
"transition": "Is_Atopic"
},
{
"distribution": 0.9625,
"transition": "Terminal"
}
]
},
{
"condition": {
"condition_type": "Date",
"operator": "<",
"year": 1970
},
"distributions": [
{
"distribution": 0.05625,
"transition": "Is_Atopic"
},
{
"distribution": 0.94375,
"transition": "Terminal"
}
]
},
{
"condition": {
"condition_type": "Date",
"operator": "<",
"year": 1980
},
"distributions": [
{
"distribution": 0.075,
"transition": "Is_Atopic"
},
{
"distribution": 0.925,
"transition": "Terminal"
}
]
},
{
"condition": {
"condition_type": "Date",
"operator": "<",
"year": 1990
},
"distributions": [
{
"distribution": 0.09375,
"transition": "Is_Atopic"
},
{
"distribution": 0.90625,
"transition": "Terminal"
}
]
},
{
"condition": {
"condition_type": "Date",
"operator": "<",
"year": 2000
},
"distributions": [
{
"distribution": 0.1125,
"transition": "Is_Atopic"
},
{
"distribution": 0.8875,
"transition": "Terminal"
}
]
},
{
"condition": {
"condition_type": "Date",
"operator": "<",
"year": 2010
},
"distributions": [
{
"distribution": 0.13125,
"transition": "Is_Atopic"
},
{
"distribution": 0.86875,
"transition": "Terminal"
}
]
},
{
"remarks": [
"After 2010, the overall prevalence of atopy settles at 15%."
],
"distributions": [
{
"distribution": 0.15,
"transition": "Is_Atopic"
},
{
"distribution": 0.85,
"transition": "Terminal"
}
]
}
]
},
"Is_Atopic": {
"type": "SetAttribute",
"attribute": "atopic",
"value": true,
"direct_transition": "Terminal"
},
"Terminal": {
"type": "Terminal"
}
},
"gmf_version": 1
}

View File

@@ -0,0 +1,191 @@
{
"name": "Atrial Fibrillation",
"specialty": "CARDIOVASCULAR DISEASE (CARDIOLOGY)",
"remarks": [
"This module is not intended to model clinical workflow, it is intended to funnel eligible patients into heart surgery."
],
"states": {
"Initial": {
"type": "Initial",
"direct_transition": "Chance_of_AFib"
},
"Terminal": {
"type": "Terminal"
},
"Chance_of_AFib": {
"type": "Delay",
"exact": {
"quantity": 1,
"unit": "months"
},
"distributed_transition": [
{
"transition": "Diagnosis",
"distribution": {
"attribute": "atrial_fibrillation_risk",
"default": 0
}
},
{
"transition": "Chance_of_AFib",
"distribution": 1
}
]
},
"Diagnosis": {
"type": "ConditionOnset",
"codes": [
{
"system": "SNOMED-CT",
"code": "49436004",
"display": "Atrial fibrillation (disorder)"
}
],
"direct_transition": "Next Wellness Visit",
"target_encounter": "Next Wellness Visit",
"assign_to_attribute": "atrial_fibrillation"
},
"Next Wellness Visit": {
"type": "Encounter",
"reason": "Diagnosis",
"telemedicine_possibility": "none",
"wellness": true,
"conditional_transition": [
{
"transition": "Verapamil",
"condition": {
"condition_type": "Date",
"operator": ">=",
"year": 1981
}
},
{
"transition": "Warfarin",
"condition": {
"condition_type": "Date",
"operator": ">=",
"year": 1954
}
},
{
"transition": "Procedure Check"
}
]
},
"Warfarin": {
"type": "MedicationOrder",
"codes": [
{
"system": "RxNorm",
"code": 855332,
"display": "Warfarin Sodium 5 MG Oral Tablet"
}
],
"direct_transition": "Digoxin",
"reason": "Diagnosis",
"chronic": true
},
"Verapamil": {
"type": "MedicationOrder",
"codes": [
{
"system": "RxNorm",
"code": 897685,
"display": "verapamil hydrochloride 80 MG Oral Tablet"
}
],
"direct_transition": "Warfarin",
"reason": "Diagnosis",
"chronic": true
},
"Digoxin": {
"type": "MedicationOrder",
"codes": [
{
"system": "RxNorm",
"code": 197604,
"display": "Digoxin 0.125 MG Oral Tablet"
}
],
"reason": "Diagnosis",
"chronic": true,
"direct_transition": "Procedure Check"
},
"Procedure Check": {
"type": "Simple",
"distributed_transition": [
{
"transition": "Catheter Ablation",
"distribution": 0.2
},
{
"transition": "Electrical Cardioversion",
"distribution": 0.8
}
]
},
"Catheter Ablation": {
"type": "Procedure",
"codes": [
{
"system": "SNOMED-CT",
"code": "18286008",
"display": "Catheter ablation of tissue of heart (procedure)"
}
],
"distribution": {
"kind": "UNIFORM",
"parameters": {
"high": 60,
"low": 30
}
},
"unit": "minutes",
"reason": "Diagnosis",
"distributed_transition": [
{
"transition": "Pacemaker",
"distribution": 0.1
},
{
"transition": "End Encounter",
"distribution": 0.9
}
]
},
"Electrical Cardioversion": {
"type": "Procedure",
"codes": [
{
"system": "SNOMED-CT",
"code": "180325003",
"display": "Direct current cardioversion (procedure)"
}
],
"distribution": {
"kind": "UNIFORM",
"parameters": {
"high": 60,
"low": 30
}
},
"unit": "minutes",
"direct_transition": "End Encounter",
"reason": "Diagnosis"
},
"End Encounter": {
"type": "EncounterEnd",
"direct_transition": "Terminal"
},
"Pacemaker": {
"type": "Device",
"code": {
"system": "SNOMED-CT",
"code": "706004007",
"display": "Implantable cardiac pacemaker (physical object)"
},
"direct_transition": "End Encounter"
}
},
"gmf_version": 2
}

View File

@@ -0,0 +1,463 @@
{
"name": "Attention Deficit Disorder",
"remarks": [
"The CDC estimates that 11% of children are diagnosed with ADHD. Althought ADHD ",
"is possible in adults we only model this in children. ",
"Source: http://www.cdc.gov/ncbddd/adhd/data.html"
],
"states": {
"Initial": {
"type": "Initial",
"remarks": [
"The CDC found that 13.2% of boys and 5.6% of girls were diagnosed with ADHD."
],
"complex_transition": [
{
"condition": {
"condition_type": "Gender",
"gender": "M"
},
"distributions": [
{
"distribution": 0.132,
"transition": "Delay_Until_ADHD"
},
{
"distribution": 0.868,
"transition": "Terminal"
}
]
},
{
"condition": {
"condition_type": "Gender",
"gender": "F"
},
"distributions": [
{
"distribution": 0.056,
"transition": "Delay_Until_ADHD"
},
{
"distribution": 0.944,
"transition": "Terminal"
}
]
}
]
},
"Delay_Until_ADHD": {
"type": "Delay",
"range": {
"low": 7,
"high": 15,
"unit": "years"
},
"direct_transition": "ADHD"
},
"ADHD": {
"type": "ConditionOnset",
"target_encounter": "ADHD_Diagnosis",
"codes": [
{
"system": "SNOMED-CT",
"code": "192127007",
"display": "Child attention deficit disorder (disorder)"
}
],
"direct_transition": "ADHD_Diagnosis"
},
"ADHD_Diagnosis": {
"type": "Encounter",
"encounter_class": "ambulatory",
"reason": "ADHD",
"codes": [
{
"system": "SNOMED-CT",
"code": "185347001",
"display": "Encounter for problem (procedure)"
}
],
"direct_transition": "ADD_Symptom1"
},
"ADD_Symptom1": {
"type": "Symptom",
"symptom": "Poor Eye Contact",
"range": {
"low": 0,
"high": 30
},
"direct_transition": "ADD_Symptom2"
},
"ADD_Symptom2": {
"type": "Symptom",
"symptom": "Delayed Verbal/Language Skills",
"range": {
"low": 0,
"high": 30
},
"direct_transition": "ADD_Symptom3"
},
"ADD_Symptom3": {
"type": "Symptom",
"symptom": "Hyperactive Behavior",
"range": {
"low": 0,
"high": 15
},
"direct_transition": "ADD_Symptom4"
},
"ADD_Symptom4": {
"type": "Symptom",
"symptom": "Inability to Focus/Concentrate",
"range": {
"low": 0,
"high": 15
},
"direct_transition": "ADD_Symptom5"
},
"ADD_Symptom5": {
"type": "Symptom",
"symptom": "Poor Socialization",
"range": {
"low": 0,
"high": 15
},
"direct_transition": "ADHD_CarePlan"
},
"ADHD_CarePlan": {
"type": "CarePlanStart",
"reason": "ADHD",
"codes": [
{
"system": "SNOMED-CT",
"code": "386522008",
"display": "Overactivity/inattention behavior management (regime/therapy)"
}
],
"activities": [
{
"system": "SNOMED-CT",
"code": "409063005",
"display": "Counseling (procedure)"
},
{
"system": "SNOMED-CT",
"code": "405783006",
"display": "Psychological assessment (procedure)"
}
],
"remarks": [
"The CDC found that as many as 17.5% of children were not receiving any form of treatment ",
"for their ADHD. Setting this at a round 15%."
],
"distributed_transition": [
{
"distribution": 0.15,
"transition": "End_Diagnosis_Encounter_without_BT",
"remarks": [
"This will just wait until adulthood before ending the ADHD and terminating the module."
]
},
{
"distribution": 0.35,
"transition": "End_Diagnosis_Encounter_with_BT",
"remarks": [
"Additionally 50% of those treated with medication will also receive behavioral ",
"therapy, for about 55% in total."
]
},
{
"distribution": 0.5,
"transition": "ADHD_Medication_Selection"
}
]
},
"Behavior_Therapy": {
"type": "Delay",
"remarks": [
"Behavior therapy is favored over medication. We give behavior therapy for ",
"awhile, until the patient reaches adulthood or the condition subsides."
],
"range": {
"low": 4,
"high": 6,
"unit": "weeks"
},
"direct_transition": "Behavior_Treatment_Encounter"
},
"Behavior_Treatment_Encounter": {
"type": "Encounter",
"encounter_class": "ambulatory",
"reason": "ADHD",
"telemedicine_possibility": "possible",
"codes": [
{
"system": "SNOMED-CT",
"code": "185347001",
"display": "Encounter for problem (procedure)"
}
],
"direct_transition": "Behavior_Treatment_Procedure"
},
"Behavior_Treatment_Procedure": {
"type": "Procedure",
"reason": "ADHD",
"codes": [
{
"system": "SNOMED-CT",
"code": "228557008",
"display": "Cognitive and behavioral therapy (regime/therapy)"
}
],
"duration": {
"low": 1,
"high": 1,
"unit": "hours"
},
"direct_transition": "End_Behavior_Treatment_Encounter"
},
"End_Behavior_Treatment_Encounter": {
"type": "EncounterEnd",
"complex_transition": [
{
"condition": {
"condition_type": "Age",
"operator": "<",
"quantity": 18,
"unit": "years"
},
"distributions": [
{
"distribution": 0.05,
"transition": "ADHD_Ends",
"remarks": [
"We give the ADHD a chance to subside (meaning the behavioral treatment ",
"has worked) during childhood. ADHD will eventually subside anyway once ",
"the patient reaches adulthood. "
]
},
{
"distribution": 0.95,
"transition": "Behavior_Therapy"
}
]
},
{
"distributions": [
{
"distribution": 1,
"transition": "ADHD_Ends"
}
]
}
]
},
"ADHD_Medication_Selection": {
"type": "Simple",
"remarks": [
"Ritalin was introduced in 1955. Strattera wasn't approved by the FDA for ",
"treating ADHD until 2006."
],
"complex_transition": [
{
"condition": {
"condition_type": "Date",
"operator": "<",
"year": 1955
},
"distributions": [
{
"distribution": 0.4,
"transition": "End_Diagnosis_Encounter_with_BT",
"remarks": [
"If no medication is available we defer additional patients to behavioral therapy. ",
"The rest get no form of treatment at all."
]
},
{
"distribution": 0.6,
"transition": "End_Diagnosis_Encounter_without_BT"
}
]
},
{
"condition": {
"condition_type": "Date",
"operator": "<",
"year": 2006
},
"distributions": [
{
"distribution": 0.6,
"transition": "Ritalin",
"remarks": [
"Even with Ritalin available not all patients are ideal candidates. ADHD medication ",
"was also prescribed at much lower rates historically. Deferring some of the remaining ",
"patients to behavioral therapy, the rest to no form of treatment."
]
},
{
"distribution": 0.15,
"transition": "End_Diagnosis_Encounter_with_BT"
},
{
"distribution": 0.25,
"transition": "End_Diagnosis_Encounter_without_BT"
}
]
},
{
"remarks": [
"With both Ritalin and Strattera available, and ADHD medication prescribed at the higher ",
"rates of the 2000's all patients that reach this state are now directed to some form of ",
"medication."
],
"distributions": [
{
"distribution": 0.5,
"transition": "Ritalin"
},
{
"distribution": 0.5,
"transition": "Strattera"
}
]
}
]
},
"Ritalin": {
"type": "MedicationOrder",
"assign_to_attribute": "adhd_medication",
"reason": "ADHD",
"codes": [
{
"system": "RxNorm",
"code": "1091392",
"display": "Methylphenidate Hydrochloride 20 MG Oral Tablet"
}
],
"distributed_transition": [
{
"distribution": 0.5,
"transition": "End_Diagnosis_Encounter_with_BT"
},
{
"distribution": 0.5,
"transition": "End_Diagnosis_Encounter_without_BT"
}
]
},
"Strattera": {
"type": "MedicationOrder",
"assign_to_attribute": "adhd_medication",
"reason": "ADHD",
"codes": [
{
"system": "RxNorm",
"code": "608139",
"display": "atomoxetine 100 MG Oral Capsule"
}
],
"distributed_transition": [
{
"distribution": 0.5,
"transition": "End_Diagnosis_Encounter_with_BT"
},
{
"distribution": 0.5,
"transition": "End_Diagnosis_Encounter_without_BT"
}
]
},
"End_Diagnosis_Encounter_without_BT": {
"type": "EncounterEnd",
"direct_transition": "Age_Guard"
},
"End_Diagnosis_Encounter_with_BT": {
"type": "EncounterEnd",
"direct_transition": "Behavior_Therapy"
},
"Age_Guard": {
"type": "Guard",
"allow": {
"condition_type": "Age",
"operator": ">=",
"quantity": 18,
"unit": "years"
},
"direct_transition": "ADHD_Ends"
},
"ADHD_Ends": {
"type": "ConditionEnd",
"condition_onset": "ADHD",
"direct_transition": "ADD_Symptom1_Ends"
},
"ADD_Symptom1_Ends": {
"type": "Symptom",
"symptom": "Poor Eye Contact",
"exact": {
"quantity": 0
},
"direct_transition": "ADD_Symptom2_Ends"
},
"ADD_Symptom2_Ends": {
"type": "Symptom",
"symptom": "Delayed Verbal/Language Skills",
"exact": {
"quantity": 0
},
"direct_transition": "ADD_Symptom3_Ends"
},
"ADD_Symptom3_Ends": {
"type": "Symptom",
"symptom": "Hyperactive Behavior",
"exact": {
"quantity": 0
},
"direct_transition": "ADD_Symptom4_Ends"
},
"ADD_Symptom4_Ends": {
"type": "Symptom",
"symptom": "Inability to Focus/Concentrate",
"exact": {
"quantity": 0
},
"direct_transition": "ADD_Symptom5_Ends"
},
"ADD_Symptom5_Ends": {
"type": "Symptom",
"symptom": "Poor Socialization",
"exact": {
"quantity": 0
},
"direct_transition": "ADHD_CarePlan_Ends"
},
"ADHD_CarePlan_Ends": {
"type": "CarePlanEnd",
"careplan": "ADHD_CarePlan",
"conditional_transition": [
{
"condition": {
"condition_type": "Attribute",
"attribute": "adhd_medication",
"operator": "is not nil"
},
"transition": "End_ADHD_Medication"
},
{
"transition": "Terminal"
}
]
},
"End_ADHD_Medication": {
"type": "MedicationEnd",
"referenced_by_attribute": "adhd_medication",
"direct_transition": "Terminal"
},
"Terminal": {
"type": "Terminal"
}
},
"gmf_version": 1
}

View File

@@ -0,0 +1,484 @@
{
"name": "Autism Spectrum Disorder",
"remarks": [
"This module models the diagnosis and management of Autism Spectrum Disorder (ASD),",
"including what was previously known as Asperger's Syndrome before DSM-5 unified the diagnosis.",
"ASD is typically diagnosed in early childhood but can be diagnosed later.",
"The module includes screening, diagnosis, interventions, and ongoing management.",
"ICD-10 code: 20544_14",
"Category: Mental and Behavioral Disorders"
],
"states": {
"Initial": {
"type": "Initial",
"direct_transition": "Age_Guard"
},
"Age_Guard": {
"type": "Guard",
"allow": {
"age_years": {
"operator": "<",
"quantity": 3
}
},
"direct_transition": "Potential_ASD_Risk"
},
"Potential_ASD_Risk": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.02,
"transition": "ASD_Prevalence_Gender_Split"
},
{
"distribution": 0.98,
"transition": "Terminal"
}
]
},
"ASD_Prevalence_Gender_Split": {
"type": "Simple",
"remarks": [
"ASD is approximately 4 times more common in males than females"
],
"conditional_transition": [
{
"condition": {
"condition_type": "Gender",
"gender": "M"
},
"transition": "Initial_Developmental_Concerns"
},
{
"condition": {
"condition_type": "Gender",
"gender": "F"
},
"transition": "Female_Prevalence_Check"
}
]
},
"Female_Prevalence_Check": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.25,
"transition": "Initial_Developmental_Concerns"
},
{
"distribution": 0.75,
"transition": "Terminal"
}
]
},
"Initial_Developmental_Concerns": {
"type": "Delay",
"range": {
"low": 12,
"high": 24,
"unit": "months"
},
"direct_transition": "Initial_Pediatric_Visit"
},
"Initial_Pediatric_Visit": {
"type": "Encounter",
"encounter_class": "ambulatory",
"reason": "Developmental concerns",
"codes": [
{
"system": "SNOMED-CT",
"code": "170258001",
"display": "Screening for developmental delay"
}
],
"direct_transition": "M_CHAT_Screening"
},
"M_CHAT_Screening": {
"type": "Procedure",
"target_encounter": "Initial_Pediatric_Visit",
"reason": "Developmental screening",
"codes": [
{
"system": "SNOMED-CT",
"code": "710081004",
"display": "Autism screening using Modified Checklist for Autism in Toddlers"
}
],
"direct_transition": "Refer_To_Specialist"
},
"Refer_To_Specialist": {
"type": "Simple",
"direct_transition": "Specialist_Evaluation"
},
"Specialist_Evaluation": {
"type": "Encounter",
"encounter_class": "ambulatory",
"reason": "Autism spectrum disorder evaluation",
"codes": [
{
"system": "SNOMED-CT",
"code": "390906007",
"display": "Child and Adolescent Psychiatry"
}
],
"direct_transition": "Comprehensive_Assessment"
},
"Comprehensive_Assessment": {
"type": "Procedure",
"target_encounter": "Specialist_Evaluation",
"reason": "Autism spectrum disorder evaluation",
"codes": [
{
"system": "SNOMED-CT",
"code": "385991005",
"display": "Developmental assessment"
}
],
"direct_transition": "ADOS_Assessment"
},
"ADOS_Assessment": {
"type": "Procedure",
"target_encounter": "Specialist_Evaluation",
"reason": "Autism spectrum disorder evaluation",
"codes": [
{
"system": "SNOMED-CT",
"code": "699690005",
"display": "Autism Diagnostic Observation Schedule"
}
],
"direct_transition": "ASD_Diagnosis"
},
"ASD_Diagnosis": {
"type": "ConditionOnset",
"target_encounter": "Specialist_Evaluation",
"assign_to_attribute": "asd_diagnosis",
"codes": [
{
"system": "ICD-10-CM",
"code": "F84.0",
"display": "Autistic disorder"
},
{
"system": "SNOMED-CT",
"code": "20544_14",
"display": "Autism spectrum disorder"
}
],
"direct_transition": "ASD_CarePlan"
},
"ASD_CarePlan": {
"type": "CarePlanStart",
"target_encounter": "Specialist_Evaluation",
"assign_to_attribute": "asd_care_plan",
"reason": "asd_diagnosis",
"codes": [
{
"system": "SNOMED-CT",
"code": "225337009",
"display": "Autism care plan"
}
],
"activities": [
{
"system": "SNOMED-CT",
"code": "10298004",
"display": "Speech therapy"
},
{
"system": "SNOMED-CT",
"code": "311401005",
"display": "Occupational therapy"
},
{
"system": "SNOMED-CT",
"code": "310092004",
"display": "Behavioral therapy"
}
],
"direct_transition": "Determine_Severity"
},
"Determine_Severity": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.3,
"transition": "Mild_ASD"
},
{
"distribution": 0.4,
"transition": "Moderate_ASD"
},
{
"distribution": 0.3,
"transition": "Severe_ASD"
}
]
},
"Mild_ASD": {
"type": "SetAttribute",
"attribute": "asd_severity",
"value": "mild",
"direct_transition": "Consider_Comorbidities"
},
"Moderate_ASD": {
"type": "SetAttribute",
"attribute": "asd_severity",
"value": "moderate",
"direct_transition": "Consider_Comorbidities"
},
"Severe_ASD": {
"type": "SetAttribute",
"attribute": "asd_severity",
"value": "severe",
"direct_transition": "Consider_Comorbidities"
},
"Consider_Comorbidities": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.3,
"transition": "ADHD_Comorbidity"
},
{
"distribution": 0.2,
"transition": "Anxiety_Comorbidity"
},
{
"distribution": 0.1,
"transition": "Epilepsy_Comorbidity"
},
{
"distribution": 0.4,
"transition": "End_Initial_Diagnosis"
}
]
},
"ADHD_Comorbidity": {
"type": "ConditionOnset",
"target_encounter": "Specialist_Evaluation",
"codes": [
{
"system": "ICD-10-CM",
"code": "F90.0",
"display": "Attention-deficit hyperactivity disorder, predominantly inattentive type"
}
],
"direct_transition": "End_Initial_Diagnosis"
},
"Anxiety_Comorbidity": {
"type": "ConditionOnset",
"target_encounter": "Specialist_Evaluation",
"codes": [
{
"system": "ICD-10-CM",
"code": "F41.9",
"display": "Anxiety disorder, unspecified"
}
],
"direct_transition": "End_Initial_Diagnosis"
},
"Epilepsy_Comorbidity": {
"type": "ConditionOnset",
"target_encounter": "Specialist_Evaluation",
"codes": [
{
"system": "ICD-10-CM",
"code": "G40.909",
"display": "Epilepsy, unspecified, not intractable, without status epilepticus"
}
],
"direct_transition": "End_Initial_Diagnosis"
},
"End_Initial_Diagnosis": {
"type": "Simple",
"direct_transition": "Consider_Medication"
},
"Consider_Medication": {
"type": "Simple",
"conditional_transition": [
{
"condition": {
"condition_type": "Attribute",
"attribute": "asd_severity",
"operator": "==",
"value": "severe"
},
"transition": "Medication_Decision"
},
{
"condition": {
"condition_type": "Attribute",
"attribute": "asd_severity",
"operator": "==",
"value": "moderate"
},
"transition": "Medication_Decision"
},
{
"transition": "Ongoing_Therapy"
}
]
},
"Medication_Decision": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.4,
"transition": "Prescribe_Risperidone"
},
{
"distribution": 0.3,
"transition": "Prescribe_Aripiprazole"
},
{
"distribution": 0.3,
"transition": "Ongoing_Therapy"
}
]
},
"Prescribe_Risperidone": {
"type": "MedicationOrder",
"reason": "asd_diagnosis",
"codes": [
{
"system": "RxNorm",
"code": "85071",
"display": "Risperidone"
}
],
"prescription": {
"dosage": {
"amount": 1,
"frequency": 1,
"period": 1,
"unit": "days"
},
"duration": {
"quantity": 1,
"unit": "years"
},
"refills": 4
},
"direct_transition": "Ongoing_Therapy"
},
"Prescribe_Aripiprazole": {
"type": "MedicationOrder",
"reason": "asd_diagnosis",
"codes": [
{
"system": "RxNorm",
"code": "349484",
"display": "Aripiprazole"
}
],
"prescription": {
"dosage": {
"amount": 5,
"frequency": 1,
"period": 1,
"unit": "days"
},
"duration": {
"quantity": 1,
"unit": "years"
},
"refills": 4
},
"direct_transition": "Ongoing_Therapy"
},
"Ongoing_Therapy": {
"type": "Delay",
"range": {
"low": 3,
"high": 6,
"unit": "months"
},
"direct_transition": "ABA_Therapy"
},
"ABA_Therapy": {
"type": "Procedure",
"codes": [
{
"system": "SNOMED-CT",
"code": "412779008",
"display": "Applied behavior analysis"
}
],
"reason": "asd_diagnosis",
"duration": {
"low": 1,
"high": 2,
"unit": "hours"
},
"direct_transition": "Speech_Therapy"
},
"Speech_Therapy": {
"type": "Procedure",
"codes": [
{
"system": "SNOMED-CT",
"code": "10298004",
"display": "Speech therapy"
}
],
"reason": "asd_diagnosis",
"duration": {
"low": 30,
"high": 60,
"unit": "minutes"
},
"direct_transition": "Occupational_Therapy"
},
"Occupational_Therapy": {
"type": "Procedure",
"codes": [
{
"system": "SNOMED-CT",
"code": "311401005",
"display": "Occupational therapy"
}
],
"reason": "asd_diagnosis",
"duration": {
"low": 30,
"high": 60,
"unit": "minutes"
},
"direct_transition": "Follow_Up_Encounter"
},
"Follow_Up_Encounter": {
"type": "Encounter",
"encounter_class": "ambulatory",
"reason": "asd_diagnosis",
"codes": [
{
"system": "SNOMED-CT",
"code": "390906007",
"display": "Child and Adolescent Psychiatry"
}
],
"direct_transition": "Progress_Assessment"
},
"Progress_Assessment": {
"type": "Procedure",
"target_encounter": "Follow_Up_Encounter",
"reason": "asd_diagnosis",
"codes": [
{
"system": "SNOMED-CT",
"code": "385991005",
"display": "Developmental assessment"
}
],
"direct_transition": "Ongoing_Care_Loop"
},
"Ongoing_Care_Loop": {
"type": "Simple",
"direct_transition": "Ongoing_Therapy"
},
"Terminal": {
"type": "Terminal"
}
}
}

View File

@@ -0,0 +1,482 @@
{
"name": "Bacterial Pneumonia",
"remarks": [
"This module simulates the onset, progression, diagnosis, treatment, and management of bacterial pneumonia.",
"Bacterial pneumonia is an infection of the lungs caused by various bacteria, most commonly Streptococcus pneumoniae.",
"Risk factors include age (very young and elderly), smoking, COPD, immunocompromised status, and other chronic conditions.",
"The module includes appropriate diagnostic tests, treatment options, and potential complications."
],
"states": {
"Initial": {
"type": "Initial",
"direct_transition": "Age_Guard"
},
"Age_Guard": {
"type": "Guard",
"allow": {
"condition_type": "Age",
"operator": ">=",
"quantity": 1,
"unit": "years"
},
"direct_transition": "Risk_Assessment"
},
"Risk_Assessment": {
"type": "Delay",
"exact": {
"quantity": 1,
"unit": "days"
},
"distributed_transition": [
{
"distribution": 0.4,
"transition": "High_Risk_Group"
},
{
"distribution": 0.6,
"transition": "Normal_Risk_Group"
}
]
},
"High_Risk_Group": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.3,
"transition": "Pneumonia_Onset"
},
{
"distribution": 0.7,
"transition": "Terminal"
}
]
},
"Normal_Risk_Group": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.05,
"transition": "Pneumonia_Onset"
},
{
"distribution": 0.95,
"transition": "Terminal"
}
]
},
"Pneumonia_Onset": {
"type": "ConditionOnset",
"target_encounter": "Pneumonia_Encounter",
"assign_to_attribute": "pneumonia",
"codes": [
{
"system": "SNOMED-CT",
"code": "53084003",
"display": "Bacterial pneumonia"
}
],
"direct_transition": "Pneumonia_Symptoms"
},
"Pneumonia_Symptoms": {
"type": "Symptom",
"symptom": "Cough",
"cause": "pneumonia",
"range": {
"low": 50,
"high": 100
},
"direct_transition": "Pneumonia_Symptom_Fever"
},
"Pneumonia_Symptom_Fever": {
"type": "Symptom",
"symptom": "Fever",
"cause": "pneumonia",
"range": {
"low": 60,
"high": 100
},
"direct_transition": "Pneumonia_Symptom_Dyspnea"
},
"Pneumonia_Symptom_Dyspnea": {
"type": "Symptom",
"symptom": "Shortness of Breath",
"cause": "pneumonia",
"range": {
"low": 40,
"high": 90
},
"direct_transition": "Pneumonia_Symptom_ChestPain"
},
"Pneumonia_Symptom_ChestPain": {
"type": "Symptom",
"symptom": "Chest Pain",
"cause": "pneumonia",
"range": {
"low": 30,
"high": 70
},
"direct_transition": "Delay_Before_Encounter"
},
"Delay_Before_Encounter": {
"type": "Delay",
"range": {
"low": 1,
"high": 3,
"unit": "days"
},
"direct_transition": "Pneumonia_Encounter"
},
"Pneumonia_Encounter": {
"type": "Encounter",
"encounter_class": "emergency",
"reason": "pneumonia",
"codes": [
{
"system": "SNOMED-CT",
"code": "185345009",
"display": "Encounter for symptom"
}
],
"direct_transition": "Pneumonia_Diagnosis"
},
"Pneumonia_Diagnosis": {
"type": "DiagnosticReport",
"codes": [
{
"system": "LOINC",
"code": "24360-0",
"display": "Bacterial identification"
}
],
"direct_transition": "Chest_Xray"
},
"Chest_Xray": {
"type": "Procedure",
"target_encounter": "Pneumonia_Encounter",
"reason": "pneumonia",
"codes": [
{
"system": "SNOMED-CT",
"code": "399208008",
"display": "Chest X-ray"
}
],
"direct_transition": "CBC_Test"
},
"CBC_Test": {
"type": "Procedure",
"target_encounter": "Pneumonia_Encounter",
"reason": "pneumonia",
"codes": [
{
"system": "LOINC",
"code": "58410-2",
"display": "Complete blood count (CBC) panel - Blood by Automated count"
}
],
"direct_transition": "Sputum_Culture"
},
"Sputum_Culture": {
"type": "Procedure",
"target_encounter": "Pneumonia_Encounter",
"reason": "pneumonia",
"codes": [
{
"system": "SNOMED-CT",
"code": "269957009",
"display": "Sputum culture"
}
],
"direct_transition": "Severity_Assessment"
},
"Severity_Assessment": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.7,
"transition": "Mild_Pneumonia"
},
{
"distribution": 0.2,
"transition": "Moderate_Pneumonia"
},
{
"distribution": 0.1,
"transition": "Severe_Pneumonia"
}
]
},
"Mild_Pneumonia": {
"type": "SetAttribute",
"attribute": "pneumonia_severity",
"value": "mild",
"direct_transition": "Prescribe_Antibiotics_Mild"
},
"Moderate_Pneumonia": {
"type": "SetAttribute",
"attribute": "pneumonia_severity",
"value": "moderate",
"direct_transition": "Prescribe_Antibiotics_Moderate"
},
"Severe_Pneumonia": {
"type": "SetAttribute",
"attribute": "pneumonia_severity",
"value": "severe",
"direct_transition": "Hospital_Admission"
},
"Prescribe_Antibiotics_Mild": {
"type": "MedicationOrder",
"target_encounter": "Pneumonia_Encounter",
"reason": "pneumonia",
"codes": [
{
"system": "RxNorm",
"code": "1658084",
"display": "Amoxicillin 500 MG Oral Tablet"
}
],
"direct_transition": "Pneumonia_Followup_Encounter"
},
"Prescribe_Antibiotics_Moderate": {
"type": "MedicationOrder",
"target_encounter": "Pneumonia_Encounter",
"reason": "pneumonia",
"codes": [
{
"system": "RxNorm",
"code": "1373737",
"display": "Azithromycin 250 MG Oral Tablet"
}
],
"direct_transition": "Pneumonia_Followup_Encounter"
},
"Hospital_Admission": {
"type": "Encounter",
"encounter_class": "inpatient",
"reason": "pneumonia",
"codes": [
{
"system": "SNOMED-CT",
"code": "183495009",
"display": "Hospital admission"
}
],
"direct_transition": "IV_Antibiotics"
},
"IV_Antibiotics": {
"type": "MedicationOrder",
"target_encounter": "Hospital_Admission",
"reason": "pneumonia",
"codes": [
{
"system": "RxNorm",
"code": "1665051",
"display": "Ceftriaxone 1000 MG Injection"
}
],
"direct_transition": "Oxygen_Therapy"
},
"Oxygen_Therapy": {
"type": "Procedure",
"target_encounter": "Hospital_Admission",
"reason": "pneumonia",
"codes": [
{
"system": "SNOMED-CT",
"code": "57485005",
"display": "Oxygen therapy"
}
],
"direct_transition": "Check_For_Complications"
},
"Check_For_Complications": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.15,
"transition": "Develop_Complications"
},
{
"distribution": 0.85,
"transition": "Hospital_Stay"
}
]
},
"Develop_Complications": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.4,
"transition": "Pleural_Effusion"
},
{
"distribution": 0.3,
"transition": "Respiratory_Failure"
},
{
"distribution": 0.3,
"transition": "Sepsis"
}
]
},
"Pleural_Effusion": {
"type": "ConditionOnset",
"target_encounter": "Hospital_Admission",
"codes": [
{
"system": "SNOMED-CT",
"code": "60046008",
"display": "Pleural effusion"
}
],
"direct_transition": "Thoracentesis"
},
"Thoracentesis": {
"type": "Procedure",
"target_encounter": "Hospital_Admission",
"codes": [
{
"system": "SNOMED-CT",
"code": "91602002",
"display": "Thoracentesis"
}
],
"direct_transition": "Extended_Hospital_Stay"
},
"Respiratory_Failure": {
"type": "ConditionOnset",
"target_encounter": "Hospital_Admission",
"codes": [
{
"system": "SNOMED-CT",
"code": "409622000",
"display": "Respiratory failure"
}
],
"direct_transition": "Mechanical_Ventilation"
},
"Mechanical_Ventilation": {
"type": "Procedure",
"target_encounter": "Hospital_Admission",
"codes": [
{
"system": "SNOMED-CT",
"code": "40617009",
"display": "Mechanical ventilation"
}
],
"direct_transition": "ICU_Stay"
},
"Sepsis": {
"type": "ConditionOnset",
"target_encounter": "Hospital_Admission",
"codes": [
{
"system": "SNOMED-CT",
"code": "91302008",
"display": "Sepsis"
}
],
"direct_transition": "Vasopressors"
},
"Vasopressors": {
"type": "MedicationOrder",
"target_encounter": "Hospital_Admission",
"codes": [
{
"system": "RxNorm",
"code": "1732136",
"display": "Norepinephrine 1 MG/ML Injectable Solution"
}
],
"direct_transition": "ICU_Stay"
},
"ICU_Stay": {
"type": "Delay",
"range": {
"low": 3,
"high": 10,
"unit": "days"
},
"direct_transition": "ICU_Outcome"
},
"ICU_Outcome": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.7,
"transition": "Extended_Hospital_Stay"
},
{
"distribution": 0.3,
"transition": "Death"
}
]
},
"Hospital_Stay": {
"type": "Delay",
"range": {
"low": 3,
"high": 7,
"unit": "days"
},
"direct_transition": "Hospital_Discharge"
},
"Extended_Hospital_Stay": {
"type": "Delay",
"range": {
"low": 7,
"high": 14,
"unit": "days"
},
"direct_transition": "Hospital_Discharge"
},
"Hospital_Discharge": {
"type": "EncounterEnd",
"direct_transition": "Pneumonia_Followup_Encounter"
},
"Pneumonia_Followup_Encounter": {
"type": "Encounter",
"encounter_class": "ambulatory",
"reason": "pneumonia",
"codes": [
{
"system": "SNOMED-CT",
"code": "390906007",
"display": "Follow-up encounter"
}
],
"direct_transition": "Followup_Chest_Xray"
},
"Followup_Chest_Xray": {
"type": "Procedure",
"target_encounter": "Pneumonia_Followup_Encounter",
"reason": "pneumonia",
"codes": [
{
"system": "SNOMED-CT",
"code": "399208008",
"display": "Chest X-ray"
}
],
"direct_transition": "Recovery_Assessment"
},
"Recovery_Assessment": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.9,
"transition": "Pneumonia_Resolves"
},
{
"distribution": 0.1,
"transition": "Pneumonia_Persists"
}
]
},
"Pneumonia_Resolves": {
"type": "ConditionEnd",
"referenced_by_attribute": "pneumonia",
"direct_transition": "End_Followup_Encounter"
},
"Pneumonia_Pers

View File

@@ -0,0 +1,482 @@
{
"name": "Bacterial Pneumonia",
"remarks": [
"This module simulates the onset, progression, diagnosis, treatment, and management of bacterial pneumonia.",
"Bacterial pneumonia is an infection of the lungs caused by various bacteria, most commonly Streptococcus pneumoniae.",
"Risk factors include age (very young and elderly), smoking, COPD, immunocompromised status, and other chronic conditions.",
"The module includes appropriate diagnostic tests, treatment options, and potential complications."
],
"states": {
"Initial": {
"type": "Initial",
"direct_transition": "Age_Guard"
},
"Age_Guard": {
"type": "Guard",
"allow": {
"condition_type": "Age",
"operator": ">=",
"quantity": 1,
"unit": "years"
},
"direct_transition": "Risk_Assessment"
},
"Risk_Assessment": {
"type": "Delay",
"exact": {
"quantity": 1,
"unit": "days"
},
"distributed_transition": [
{
"distribution": 0.4,
"transition": "High_Risk_Group"
},
{
"distribution": 0.6,
"transition": "Normal_Risk_Group"
}
]
},
"High_Risk_Group": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.3,
"transition": "Pneumonia_Onset"
},
{
"distribution": 0.7,
"transition": "Terminal"
}
]
},
"Normal_Risk_Group": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.05,
"transition": "Pneumonia_Onset"
},
{
"distribution": 0.95,
"transition": "Terminal"
}
]
},
"Pneumonia_Onset": {
"type": "ConditionOnset",
"target_encounter": "Pneumonia_Encounter",
"assign_to_attribute": "pneumonia",
"codes": [
{
"system": "SNOMED-CT",
"code": "53084003",
"display": "Bacterial pneumonia"
}
],
"direct_transition": "Pneumonia_Symptoms"
},
"Pneumonia_Symptoms": {
"type": "Symptom",
"symptom": "Cough",
"cause": "pneumonia",
"range": {
"low": 50,
"high": 100
},
"direct_transition": "Pneumonia_Symptom_Fever"
},
"Pneumonia_Symptom_Fever": {
"type": "Symptom",
"symptom": "Fever",
"cause": "pneumonia",
"range": {
"low": 60,
"high": 100
},
"direct_transition": "Pneumonia_Symptom_Dyspnea"
},
"Pneumonia_Symptom_Dyspnea": {
"type": "Symptom",
"symptom": "Shortness of Breath",
"cause": "pneumonia",
"range": {
"low": 40,
"high": 90
},
"direct_transition": "Pneumonia_Symptom_ChestPain"
},
"Pneumonia_Symptom_ChestPain": {
"type": "Symptom",
"symptom": "Chest Pain",
"cause": "pneumonia",
"range": {
"low": 30,
"high": 70
},
"direct_transition": "Delay_Before_Encounter"
},
"Delay_Before_Encounter": {
"type": "Delay",
"range": {
"low": 1,
"high": 3,
"unit": "days"
},
"direct_transition": "Pneumonia_Encounter"
},
"Pneumonia_Encounter": {
"type": "Encounter",
"encounter_class": "emergency",
"reason": "pneumonia",
"codes": [
{
"system": "SNOMED-CT",
"code": "185345009",
"display": "Encounter for symptom"
}
],
"direct_transition": "Pneumonia_Diagnosis"
},
"Pneumonia_Diagnosis": {
"type": "DiagnosticReport",
"codes": [
{
"system": "LOINC",
"code": "24360-0",
"display": "Bacterial identification"
}
],
"direct_transition": "Chest_Xray"
},
"Chest_Xray": {
"type": "Procedure",
"target_encounter": "Pneumonia_Encounter",
"reason": "pneumonia",
"codes": [
{
"system": "SNOMED-CT",
"code": "399208008",
"display": "Chest X-ray"
}
],
"direct_transition": "CBC_Test"
},
"CBC_Test": {
"type": "Procedure",
"target_encounter": "Pneumonia_Encounter",
"reason": "pneumonia",
"codes": [
{
"system": "LOINC",
"code": "58410-2",
"display": "Complete blood count (CBC) panel - Blood by Automated count"
}
],
"direct_transition": "Sputum_Culture"
},
"Sputum_Culture": {
"type": "Procedure",
"target_encounter": "Pneumonia_Encounter",
"reason": "pneumonia",
"codes": [
{
"system": "SNOMED-CT",
"code": "269957009",
"display": "Sputum culture"
}
],
"direct_transition": "Severity_Assessment"
},
"Severity_Assessment": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.7,
"transition": "Mild_Pneumonia"
},
{
"distribution": 0.2,
"transition": "Moderate_Pneumonia"
},
{
"distribution": 0.1,
"transition": "Severe_Pneumonia"
}
]
},
"Mild_Pneumonia": {
"type": "SetAttribute",
"attribute": "pneumonia_severity",
"value": "mild",
"direct_transition": "Prescribe_Antibiotics_Mild"
},
"Moderate_Pneumonia": {
"type": "SetAttribute",
"attribute": "pneumonia_severity",
"value": "moderate",
"direct_transition": "Prescribe_Antibiotics_Moderate"
},
"Severe_Pneumonia": {
"type": "SetAttribute",
"attribute": "pneumonia_severity",
"value": "severe",
"direct_transition": "Hospital_Admission"
},
"Prescribe_Antibiotics_Mild": {
"type": "MedicationOrder",
"target_encounter": "Pneumonia_Encounter",
"reason": "pneumonia",
"codes": [
{
"system": "RxNorm",
"code": "1658084",
"display": "Amoxicillin 500 MG Oral Tablet"
}
],
"direct_transition": "Pneumonia_Followup_Encounter"
},
"Prescribe_Antibiotics_Moderate": {
"type": "MedicationOrder",
"target_encounter": "Pneumonia_Encounter",
"reason": "pneumonia",
"codes": [
{
"system": "RxNorm",
"code": "1373737",
"display": "Azithromycin 250 MG Oral Tablet"
}
],
"direct_transition": "Pneumonia_Followup_Encounter"
},
"Hospital_Admission": {
"type": "Encounter",
"encounter_class": "inpatient",
"reason": "pneumonia",
"codes": [
{
"system": "SNOMED-CT",
"code": "183495009",
"display": "Hospital admission"
}
],
"direct_transition": "IV_Antibiotics"
},
"IV_Antibiotics": {
"type": "MedicationOrder",
"target_encounter": "Hospital_Admission",
"reason": "pneumonia",
"codes": [
{
"system": "RxNorm",
"code": "1665051",
"display": "Ceftriaxone 1000 MG Injection"
}
],
"direct_transition": "Oxygen_Therapy"
},
"Oxygen_Therapy": {
"type": "Procedure",
"target_encounter": "Hospital_Admission",
"reason": "pneumonia",
"codes": [
{
"system": "SNOMED-CT",
"code": "57485005",
"display": "Oxygen therapy"
}
],
"direct_transition": "Check_For_Complications"
},
"Check_For_Complications": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.15,
"transition": "Develop_Complications"
},
{
"distribution": 0.85,
"transition": "Hospital_Stay"
}
]
},
"Develop_Complications": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.4,
"transition": "Pleural_Effusion"
},
{
"distribution": 0.3,
"transition": "Respiratory_Failure"
},
{
"distribution": 0.3,
"transition": "Sepsis"
}
]
},
"Pleural_Effusion": {
"type": "ConditionOnset",
"target_encounter": "Hospital_Admission",
"codes": [
{
"system": "SNOMED-CT",
"code": "60046008",
"display": "Pleural effusion"
}
],
"direct_transition": "Thoracentesis"
},
"Thoracentesis": {
"type": "Procedure",
"target_encounter": "Hospital_Admission",
"codes": [
{
"system": "SNOMED-CT",
"code": "91602002",
"display": "Thoracentesis"
}
],
"direct_transition": "Extended_Hospital_Stay"
},
"Respiratory_Failure": {
"type": "ConditionOnset",
"target_encounter": "Hospital_Admission",
"codes": [
{
"system": "SNOMED-CT",
"code": "409622000",
"display": "Respiratory failure"
}
],
"direct_transition": "Mechanical_Ventilation"
},
"Mechanical_Ventilation": {
"type": "Procedure",
"target_encounter": "Hospital_Admission",
"codes": [
{
"system": "SNOMED-CT",
"code": "40617009",
"display": "Mechanical ventilation"
}
],
"direct_transition": "ICU_Stay"
},
"Sepsis": {
"type": "ConditionOnset",
"target_encounter": "Hospital_Admission",
"codes": [
{
"system": "SNOMED-CT",
"code": "91302008",
"display": "Sepsis"
}
],
"direct_transition": "Vasopressors"
},
"Vasopressors": {
"type": "MedicationOrder",
"target_encounter": "Hospital_Admission",
"codes": [
{
"system": "RxNorm",
"code": "1732136",
"display": "Norepinephrine 1 MG/ML Injectable Solution"
}
],
"direct_transition": "ICU_Stay"
},
"ICU_Stay": {
"type": "Delay",
"range": {
"low": 3,
"high": 10,
"unit": "days"
},
"direct_transition": "ICU_Outcome"
},
"ICU_Outcome": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.7,
"transition": "Extended_Hospital_Stay"
},
{
"distribution": 0.3,
"transition": "Death"
}
]
},
"Hospital_Stay": {
"type": "Delay",
"range": {
"low": 3,
"high": 7,
"unit": "days"
},
"direct_transition": "Hospital_Discharge"
},
"Extended_Hospital_Stay": {
"type": "Delay",
"range": {
"low": 7,
"high": 14,
"unit": "days"
},
"direct_transition": "Hospital_Discharge"
},
"Hospital_Discharge": {
"type": "EncounterEnd",
"direct_transition": "Pneumonia_Followup_Encounter"
},
"Pneumonia_Followup_Encounter": {
"type": "Encounter",
"encounter_class": "ambulatory",
"reason": "pneumonia",
"codes": [
{
"system": "SNOMED-CT",
"code": "390906007",
"display": "Follow-up encounter"
}
],
"direct_transition": "Followup_Chest_Xray"
},
"Followup_Chest_Xray": {
"type": "Procedure",
"target_encounter": "Pneumonia_Followup_Encounter",
"reason": "pneumonia",
"codes": [
{
"system": "SNOMED-CT",
"code": "399208008",
"display": "Chest X-ray"
}
],
"direct_transition": "Recovery_Assessment"
},
"Recovery_Assessment": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.9,
"transition": "Pneumonia_Resolves"
},
{
"distribution": 0.1,
"transition": "Pneumonia_Persists"
}
]
},
"Pneumonia_Resolves": {
"type": "ConditionEnd",
"referenced_by_attribute": "pneumonia",
"direct_transition": "End_Followup_Encounter"
},
"Pneumonia_Pers

View File

@@ -0,0 +1,807 @@
{
"name": "Bone Marrow Transplant",
"remarks": [
"Bone marrow transplants are sometimes used to treat patients with cancer or other immune deficiencies.",
"",
"Recipients may spend a few weeks in the hospital or nearby, undergoing frequent blood tests and appointments to monitor response to the transplant.",
"",
"Post transplant complications are not modeled.",
"",
"In a study of 2017 data, 60% of transplants were autologous, and 40% were allogeneic. This can be further refined based on the root cause -- i.e., why the patient is receiving a bone marrow transplant, but that is not modeled here.",
"",
"The use of peripheral-blood stem cells has increased and now accounts for 75% of stem-cell transplants from unrelated adult donors.",
"",
"References",
"- https://www.mayoclinic.org/tests-procedures/bone-marrow-transplant/about/pac-20384854",
"- https://www.ncbi.nlm.nih.gov/books/NBK536951",
"- https://doi.org/10.1038/s41409-019-0465-9",
"- https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3816375/",
"- https://bloodstemcell.hrsa.gov/data/donation-and-transplantation-statistics",
""
],
"states": {
"Initial": {
"type": "Initial",
"direct_transition": "Guard Until Bone Marrow Transplant"
},
"Donor Check": {
"type": "Simple",
"distributed_transition": [
{
"transition": "from own body (autologous transplant)",
"distribution": 0.6
},
{
"transition": "from a donor (allogeneic marrow)",
"distribution": 0.1
},
{
"transition": "from a donor (allogeneic stem cells)",
"distribution": 0.3
}
]
},
"from own body (autologous transplant)": {
"type": "Procedure",
"codes": [
{
"system": "SNOMED-CT",
"code": "58776007",
"display": "Autologous bone marrow transplant (procedure)"
}
],
"distribution": {
"kind": "UNIFORM",
"parameters": {
"high": 120,
"low": 60
}
},
"unit": "minutes",
"direct_transition": "History of autologous bone marrow transplant"
},
"History of allotransplantation of bone marrow": {
"type": "ConditionOnset",
"codes": [
{
"system": "SNOMED-CT",
"code": "152621000119105",
"display": "History of allotransplantation of bone marrow (situation)"
}
],
"direct_transition": "End Wait",
"assign_to_attribute": "history_of_bone_marrow_transplant"
},
"History of autologous bone marrow transplant": {
"type": "ConditionOnset",
"codes": [
{
"system": "SNOMED-CT",
"code": "108631000119101",
"display": "History of autologous bone marrow transplant (situation)"
}
],
"assign_to_attribute": "history_of_bone_marrow_transplant",
"direct_transition": "End Wait"
},
"Set Recovery LOS": {
"type": "SetAttribute",
"attribute": "bone_marrow_transplant_los",
"direct_transition": "Recovery",
"distribution": {
"kind": "EXPONENTIAL",
"round": false,
"parameters": {
"mean": 14
}
}
},
"Recovery": {
"type": "Counter",
"attribute": "bone_marrow_transplant_los",
"action": "decrement",
"direct_transition": "Postoperative care"
},
"Continue": {
"type": "Delay",
"distribution": {
"kind": "EXACT",
"parameters": {
"value": 1
}
},
"unit": "days",
"conditional_transition": [
{
"transition": "Recovery",
"condition": {
"condition_type": "Attribute",
"attribute": "bone_marrow_transplant_los",
"operator": ">",
"value": 0
}
},
{
"transition": "End Transplant Encounter"
}
]
},
"Record_CBC_Panel": {
"type": "DiagnosticReport",
"number_of_observations": 4,
"codes": [
{
"system": "LOINC",
"code": "58410-2",
"display": "CBC panel - Blood by Automated count"
}
],
"observations": [
{
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "6690-2",
"display": "Leukocytes [#/volume] in Blood by Automated count"
}
],
"unit": "10*3/uL",
"range": {
"low": 3.5,
"high": 10.5
}
},
{
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "789-8",
"display": "Erythrocytes [#/volume] in Blood by Automated count"
}
],
"unit": "10*6/uL",
"range": {
"low": 3.9,
"high": 5.5
}
},
{
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "718-7",
"display": "Hemoglobin [Mass/volume] in Blood"
}
],
"unit": "g/dL",
"range": {
"low": 12,
"high": 17.5
}
},
{
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "4544-3",
"display": "Hematocrit [Volume Fraction] of Blood by Automated count"
}
],
"unit": "%",
"range": {
"low": 35,
"high": 50
}
},
{
"category": "laboratory",
"unit": "fL",
"codes": [
{
"system": "LOINC",
"code": "787-2",
"display": "MCV [Entitic volume] by Automated count"
}
],
"range": {
"low": 80,
"high": 95
}
},
{
"category": "laboratory",
"unit": "pg",
"codes": [
{
"system": "LOINC",
"code": "785-6",
"display": "MCH [Entitic mass] by Automated count"
}
],
"range": {
"low": 27,
"high": 33
}
},
{
"category": "laboratory",
"unit": "g/dL",
"codes": [
{
"system": "LOINC",
"code": "786-4",
"display": "MCHC [Mass/volume] by Automated count"
}
],
"range": {
"low": 33,
"high": 36
}
},
{
"category": "laboratory",
"unit": "fL",
"codes": [
{
"system": "LOINC",
"code": "21000-5",
"display": "Erythrocyte distribution width [Entitic volume] by Automated count"
}
],
"range": {
"low": 39,
"high": 46
}
},
{
"category": "laboratory",
"unit": "10*3/uL",
"codes": [
{
"system": "LOINC",
"code": "777-3",
"display": "Platelets [#/volume] in Blood by Automated count"
}
],
"range": {
"low": 150,
"high": 450
}
},
{
"category": "laboratory",
"unit": "fL",
"codes": [
{
"system": "LOINC",
"code": "32207-3",
"display": "Platelet distribution width [Entitic volume] in Blood by Automated count"
}
],
"range": {
"low": 150,
"high": 520
}
},
{
"category": "laboratory",
"unit": "fL",
"codes": [
{
"system": "LOINC",
"code": "32623-1",
"display": "Platelet mean volume [Entitic volume] in Blood by Automated count"
}
],
"range": {
"low": 9.4,
"high": 12.3
}
}
],
"direct_transition": "Hematologic disorder medication review"
},
"Hematologic disorder medication review": {
"type": "Procedure",
"codes": [
{
"system": "SNOMED-CT",
"code": "473220001",
"display": "Hematologic disorder medication review (procedure)"
}
],
"distribution": {
"kind": "UNIFORM",
"parameters": {
"high": 15,
"low": 10
}
},
"unit": "minutes",
"reason": "history_of_bone_marrow_transplant",
"direct_transition": "Continue"
},
"Postoperative care": {
"type": "Procedure",
"codes": [
{
"system": "SNOMED-CT",
"code": "133899007",
"display": "Postoperative care (regime/therapy)"
}
],
"distribution": {
"kind": "UNIFORM",
"parameters": {
"high": 60,
"low": 30
}
},
"unit": "minutes",
"direct_transition": "Record_CBC_Panel",
"reason": "history_of_bone_marrow_transplant"
},
"Wait_for_Consultation": {
"type": "Delay",
"distribution": {
"kind": "GAUSSIAN",
"parameters": {
"mean": 3,
"standardDeviation": 1
}
},
"unit": "months",
"direct_transition": "Consultation"
},
"Consultation": {
"type": "Encounter",
"encounter_class": "ambulatory",
"reason": "Awaiting transplantation of bone marrow",
"telemedicine_possibility": "none",
"codes": [
{
"system": "SNOMED-CT",
"code": "386395000",
"display": "Preoperative coordination (regime/therapy)"
}
],
"direct_transition": "Record_CBC_Preop"
},
"Hematologic_disorder_medication_review": {
"type": "Procedure",
"codes": [
{
"system": "SNOMED-CT",
"code": "473220001",
"display": "Hematologic disorder medication review (procedure)"
}
],
"distribution": {
"kind": "UNIFORM",
"parameters": {
"high": 30,
"low": 20
}
},
"unit": "minutes",
"reason": "Awaiting transplantation of bone marrow",
"direct_transition": "Treatment failure risk education"
},
"Awaiting transplantation of bone marrow": {
"type": "ConditionOnset",
"codes": [
{
"system": "SNOMED-CT",
"code": "698303004",
"display": "Awaiting transplantation of bone marrow (situation)"
}
],
"direct_transition": "Wait_for_Consultation",
"target_encounter": "Consultation",
"assign_to_attribute": "bone_marrow_dental_reason"
},
"Treatment failure risk education": {
"type": "Procedure",
"codes": [
{
"system": "SNOMED-CT",
"code": "304532001",
"display": "Treatment failure risk education (procedure)"
}
],
"distribution": {
"kind": "UNIFORM",
"parameters": {
"high": 15,
"low": 10
}
},
"unit": "minutes",
"direct_transition": "Treatment side effects education",
"reason": "Awaiting transplantation of bone marrow"
},
"Treatment side effects education": {
"type": "Procedure",
"codes": [
{
"system": "SNOMED-CT",
"code": "304531008",
"display": "Treatment side effects education (procedure)"
}
],
"distribution": {
"kind": "UNIFORM",
"parameters": {
"high": 15,
"low": 10
}
},
"unit": "minutes",
"reason": "Awaiting transplantation of bone marrow",
"direct_transition": "Pre-operative chemotherapy"
},
"Referral": {
"type": "Procedure",
"codes": [
{
"system": "SNOMED-CT",
"code": "306316000",
"display": "Referral to transplant surgeon (procedure)"
}
],
"distribution": {
"kind": "UNIFORM",
"parameters": {
"high": 15,
"low": 10
}
},
"unit": "minutes",
"reason": "Awaiting transplantation of bone marrow",
"direct_transition": "End Consultation"
},
"End Consultation": {
"type": "EncounterEnd",
"direct_transition": "Initiate_Dental_Cleaning"
},
"Transplant Encounter": {
"type": "Encounter",
"encounter_class": "inpatient",
"reason": "Awaiting transplantation of bone marrow",
"telemedicine_possibility": "none",
"codes": [
{
"system": "SNOMED-CT",
"code": "305432006",
"display": "Admission to surgical transplant department (procedure)"
}
],
"direct_transition": "Donor Check"
},
"End Wait": {
"type": "ConditionEnd",
"direct_transition": "Set Recovery LOS",
"condition_onset": "Awaiting transplantation of bone marrow"
},
"Initiate_Dental_Cleaning": {
"type": "SetAttribute",
"attribute": "dental_referral",
"value_attribute": "bone_marrow_dental_reason",
"direct_transition": "Wait_for_Cleaning"
},
"Wait_for_Cleaning": {
"type": "Delay",
"distribution": {
"kind": "UNIFORM",
"parameters": {
"high": 7,
"low": 1
}
},
"unit": "days",
"direct_transition": "Check_Cleaning_Status"
},
"Check_Cleaning_Status": {
"type": "Simple",
"conditional_transition": [
{
"transition": "Wait_for_Cleaning",
"condition": {
"condition_type": "Attribute",
"attribute": "dental_referral",
"operator": "is not nil"
}
},
{
"transition": "Wait_for_Transplant"
}
]
},
"End Transplant Encounter": {
"type": "EncounterEnd",
"direct_transition": "End Bone Marrow"
},
"Guard Until Bone Marrow Transplant": {
"type": "Guard",
"allow": {
"condition_type": "Attribute",
"attribute": "bone_marrow",
"operator": "is not nil"
},
"direct_transition": "Awaiting transplantation of bone marrow"
},
"End Bone Marrow": {
"type": "SetAttribute",
"attribute": "bone_marrow",
"value": null,
"direct_transition": "Guard Until Bone Marrow Transplant"
},
"Wait_for_Transplant": {
"type": "Delay",
"distribution": {
"kind": "UNIFORM",
"parameters": {
"high": 21,
"low": 3
}
},
"unit": "days",
"direct_transition": "Transplant Encounter"
},
"Pre-operative chemotherapy": {
"type": "Procedure",
"codes": [
{
"system": "SNOMED-CT",
"code": "394894008",
"display": "Pre-operative chemotherapy (procedure)"
}
],
"distribution": {
"kind": "UNIFORM",
"parameters": {
"high": 120,
"low": 60
}
},
"unit": "minutes",
"direct_transition": "Referral",
"reason": "Awaiting transplantation of bone marrow"
},
"History of peripheral stem cell transplant": {
"type": "ConditionOnset",
"codes": [
{
"system": "SNOMED-CT",
"code": "153351000119102",
"display": "History of peripheral stem cell transplant (situation)"
}
],
"direct_transition": "End Wait",
"assign_to_attribute": "history_of_bone_marrow_transplant"
},
"from a donor (allogeneic stem cells)": {
"type": "Procedure",
"codes": [
{
"system": "SNOMED-CT",
"code": "234336002",
"display": "Hemopoietic stem cell transplant (procedure)"
}
],
"distribution": {
"kind": "UNIFORM",
"parameters": {
"high": 120,
"low": 60
}
},
"unit": "minutes",
"direct_transition": "History of peripheral stem cell transplant",
"reason": "Awaiting transplantation of bone marrow"
},
"from a donor (allogeneic marrow)": {
"type": "Procedure",
"codes": [
{
"system": "SNOMED-CT",
"code": "58390007",
"display": "Allogeneic bone marrow transplantation (procedure)"
}
],
"distribution": {
"kind": "UNIFORM",
"parameters": {
"high": 120,
"low": 60
}
},
"unit": "minutes",
"direct_transition": "History of allotransplantation of bone marrow"
},
"Record_CBC_Preop": {
"type": "DiagnosticReport",
"number_of_observations": 4,
"codes": [
{
"system": "LOINC",
"code": "58410-2",
"display": "CBC panel - Blood by Automated count"
}
],
"observations": [
{
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "6690-2",
"display": "Leukocytes [#/volume] in Blood by Automated count"
}
],
"unit": "10*3/uL",
"range": {
"low": 0.5,
"high": 5
}
},
{
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "789-8",
"display": "Erythrocytes [#/volume] in Blood by Automated count"
}
],
"unit": "10*6/uL",
"range": {
"low": 3.9,
"high": 5.5
}
},
{
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "718-7",
"display": "Hemoglobin [Mass/volume] in Blood"
}
],
"unit": "g/dL",
"range": {
"low": 6,
"high": 15
}
},
{
"category": "laboratory",
"codes": [
{
"system": "LOINC",
"code": "4544-3",
"display": "Hematocrit [Volume Fraction] of Blood by Automated count"
}
],
"unit": "%",
"range": {
"low": 25,
"high": 35
}
},
{
"category": "laboratory",
"unit": "fL",
"codes": [
{
"system": "LOINC",
"code": "787-2",
"display": "MCV [Entitic volume] by Automated count"
}
],
"range": {
"low": 80,
"high": 95
}
},
{
"category": "laboratory",
"unit": "pg",
"codes": [
{
"system": "LOINC",
"code": "785-6",
"display": "MCH [Entitic mass] by Automated count"
}
],
"range": {
"low": 27,
"high": 33
}
},
{
"category": "laboratory",
"unit": "g/dL",
"codes": [
{
"system": "LOINC",
"code": "786-4",
"display": "MCHC [Mass/volume] by Automated count"
}
],
"range": {
"low": 33,
"high": 36
}
},
{
"category": "laboratory",
"unit": "fL",
"codes": [
{
"system": "LOINC",
"code": "21000-5",
"display": "Erythrocyte distribution width [Entitic volume] by Automated count"
}
],
"range": {
"low": 39,
"high": 46
}
},
{
"category": "laboratory",
"unit": "10*3/uL",
"codes": [
{
"system": "LOINC",
"code": "777-3",
"display": "Platelets [#/volume] in Blood by Automated count"
}
],
"range": {
"low": 150,
"high": 450
}
},
{
"category": "laboratory",
"unit": "fL",
"codes": [
{
"system": "LOINC",
"code": "32207-3",
"display": "Platelet distribution width [Entitic volume] in Blood by Automated count"
}
],
"range": {
"low": 150,
"high": 520
}
},
{
"category": "laboratory",
"unit": "fL",
"codes": [
{
"system": "LOINC",
"code": "32623-1",
"display": "Platelet mean volume [Entitic volume] in Blood by Automated count"
}
],
"range": {
"low": 9.4,
"high": 12.3
}
}
],
"direct_transition": "Hematologic_disorder_medication_review"
}
},
"gmf_version": 2
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,323 @@
{
"name": "chemotherapy_breast",
"remarks": [
"This module consists of the different chemo drugs and goes through the adjuvant chemo cycle after surgery. "
],
"states": {
"Initial": {
"type": "Initial",
"direct_transition": "Set chemo counter"
},
"Cyclophosphamide": {
"type": "MedicationOrder",
"codes": [
{
"system": "RxNorm",
"code": 1734919,
"display": "Cyclophosphamide 1000 MG Injection"
}
],
"direct_transition": "Adjuvant Chemotherapy Procedure",
"assign_to_attribute": "chemoMed",
"reason": "breast_cancer_condition",
"administration": true
},
"Anthracyclines": {
"type": "Simple",
"distributed_transition": [
{
"transition": "Doxorubicin",
"distribution": 0.5
},
{
"transition": "Epirubicin",
"distribution": 0.5
}
]
},
"Carboplatin": {
"type": "MedicationOrder",
"codes": [
{
"system": "RxNorm",
"code": 597195,
"display": "Carboplatin 10 MG/ML Injectable Solution"
}
],
"direct_transition": "Adjuvant Chemotherapy Procedure",
"assign_to_attribute": "chemoMed",
"reason": "breast_cancer_condition",
"administration": true
},
"Taxanes": {
"type": "Simple",
"direct_transition": "Paclitaxel"
},
"5-fluorouracil": {
"type": "MedicationOrder",
"codes": [
{
"system": "RxNorm",
"code": 1791701,
"display": "10 ML Fluorouracil 50 MG/ML Injection"
}
],
"direct_transition": "Adjuvant Chemotherapy Procedure",
"assign_to_attribute": "chemoMed",
"reason": "breast_cancer_condition",
"administration": true
},
"Doxorubicin": {
"type": "MedicationOrder",
"codes": [
{
"system": "RxNorm",
"code": 1790099,
"display": "10 ML Doxorubicin Hydrochloride 2 MG/ML Injection"
}
],
"direct_transition": "Adjuvant Chemotherapy Procedure",
"remarks": [
"- Doxorubicin (Adriamycin)",
"- Epriubicin (Ellence) ",
"https://www.cancer.org/cancer/breast-cancer/treatment/chemotherapy-for-breast-cancer.html"
],
"assign_to_attribute": "chemoMed",
"reason": "breast_cancer_condition",
"administration": true
},
"Epirubicin": {
"type": "MedicationOrder",
"codes": [
{
"system": "RxNorm",
"code": 1732186,
"display": "100 ML Epirubicin Hydrochloride 2 MG/ML Injection"
}
],
"direct_transition": "Adjuvant Chemotherapy Procedure",
"assign_to_attribute": "chemoMed",
"reason": "breast_cancer_condition",
"administration": true
},
"Paclitaxel": {
"type": "MedicationOrder",
"codes": [
{
"system": "RxNorm",
"code": 583214,
"display": "Paclitaxel 100 MG Injection"
}
],
"direct_transition": "Adjuvant Chemotherapy Procedure",
"assign_to_attribute": "chemoMed",
"reason": "breast_cancer_condition",
"administration": true
},
"Adjuvant Chemotherapy Procedure": {
"type": "Procedure",
"codes": [
{
"system": "SNOMED-CT",
"code": "367336001",
"display": "Chemotherapy (procedure)"
}
],
"duration": {
"low": 0,
"high": 2,
"unit": "hours"
},
"direct_transition": "End Current Adjuvant Chemo Medication"
},
"Terminal": {
"type": "Terminal"
},
"End Current Chemo Treatment": {
"type": "EncounterEnd",
"conditional_transition": [
{
"transition": "Increment Chemo Counter",
"condition": {
"condition_type": "Attribute",
"attribute": "breast_cancer_chemoCount",
"operator": "<",
"value": 7
}
},
{
"transition": "Terminal"
}
]
},
"Increment Chemo Counter": {
"type": "Counter",
"attribute": "breast_cancer_chemoCount",
"action": "increment",
"direct_transition": "Delay Until Next Cycle (3 Weeks)"
},
"Start New Cycle": {
"type": "Encounter",
"encounter_class": "ambulatory",
"reason": "Breast Cancer",
"codes": [
{
"system": "SNOMED-CT",
"code": "185347001",
"display": "Encounter for problem (procedure)"
}
],
"direct_transition": "Choose Chemo Drug"
},
"Set chemo counter": {
"type": "SetAttribute",
"attribute": "breast_cancer_chemoCount",
"value": 0,
"remarks": [
"https://www.cancer.org/cancer/breast-cancer/treatment/chemotherapy-for-breast-cancer.html",
"",
"Which chemotherapy drugs are used for breast cancer?",
"In most cases (especially as adjuvant or neoadjuvant treatment), chemo is most effective when combinations of drugs are used. Today, doctors use many different combinations, and it's not clear that any single combination is clearly the best.",
"",
"The most common drugs used for adjuvant and neoadjuvant chemo include:",
"Anthracyclines, such as doxorubicin (Adriamycin) and epirubicin (Ellence)",
"Taxanes, such as paclitaxel (Taxol) and docetaxel (Taxotere)",
"5-fluorouracil (5-FU)",
"Cyclophosphamide (Cytoxan)",
"Carboplatin (Paraplatin)",
"Most often, combinations of 2 or 3 of these drugs are used."
],
"direct_transition": "Choose Chemo Drug"
},
"Delay Until Next Cycle (3 Weeks)": {
"type": "Delay",
"direct_transition": "Start New Cycle",
"range": {
"low": 19,
"high": 23,
"unit": "days"
}
},
"Choose Chemo Drug": {
"type": "Simple",
"remarks": [
"https://www.cancer.org/cancer/breast-cancer/treatment/chemotherapy-for-breast-cancer.html",
"",
"Which chemotherapy drugs are used for breast cancer?",
"In most cases (especially as adjuvant or neoadjuvant treatment), chemo is most effective when combinations of drugs are used. Today, doctors use many different combinations, and it's not clear that any single combination is clearly the best.",
"",
"The most common drugs used for adjuvant and neoadjuvant chemo include:",
"Anthracyclines, such as doxorubicin (Adriamycin) and epirubicin (Ellence)",
"Taxanes, such as paclitaxel (Taxol) and docetaxel (Taxotere)",
"5-fluorouracil (5-FU)",
"Cyclophosphamide (Cytoxan)",
"Carboplatin (Paraplatin)",
"Most often, combinations of 2 or 3 of these drugs are used."
],
"complex_transition": [
{
"condition": {
"condition_type": "PriorState",
"name": "Cyclophosphamide"
},
"distributions": [
{
"transition": "Cyclophosphamide",
"distribution": 1
}
]
},
{
"condition": {
"condition_type": "PriorState",
"name": "Doxorubicin"
},
"distributions": [
{
"transition": "Doxorubicin",
"distribution": 1
}
]
},
{
"condition": {
"condition_type": "PriorState",
"name": "Epirubicin"
},
"distributions": [
{
"transition": "Epirubicin",
"distribution": 1
}
]
},
{
"distributions": [
{
"transition": "Carboplatin",
"distribution": 1
}
],
"condition": {
"condition_type": "PriorState",
"name": "Carboplatin"
}
},
{
"condition": {
"condition_type": "PriorState",
"name": "Paclitaxel"
},
"distributions": [
{
"transition": "Paclitaxel",
"distribution": 1
}
]
},
{
"condition": {
"condition_type": "PriorState",
"name": "5-fluorouracil"
},
"distributions": [
{
"transition": "5-fluorouracil",
"distribution": 1
}
]
},
{
"distributions": [
{
"transition": "Cyclophosphamide",
"distribution": 0.3
},
{
"transition": "Anthracyclines",
"distribution": 0.3
},
{
"transition": "Carboplatin",
"distribution": 0.05
},
{
"transition": "Taxanes",
"distribution": 0.3
},
{
"transition": "5-fluorouracil",
"distribution": 0.05
}
]
}
]
},
"End Current Adjuvant Chemo Medication": {
"type": "MedicationEnd",
"direct_transition": "End Current Chemo Treatment",
"referenced_by_attribute": "chemoMed"
}
},
"gmf_version": 1
}

View File

@@ -0,0 +1,431 @@
{
"name": "Hormone_Diagnosis",
"remarks": [
"This module checks for HER2 and then assigns either HER2 positive/negative. This follows suit for ER and PR. Finally, it accounts for the Triple negative factor at the end. "
],
"states": {
"Initial": {
"type": "Initial",
"direct_transition": "Human_Epidermal_Growth_Factor_Receptor_2__HER2__Detection___Fluorescence_in_situ_Hybridization__FISH_"
},
"Terminal": {
"type": "Terminal"
},
"Human_Epidermal_Growth_Factor_Receptor_2__HER2__Detection___Fluorescence_in_situ_Hybridization__FISH_": {
"type": "Procedure",
"codes": [
{
"system": "SNOMED-CT",
"code": "434363004",
"display": "Human epidermal growth factor receptor 2 gene detection by fluorescence in situ hybridization (procedure)"
}
],
"duration": {
"low": 1,
"high": 2,
"unit": "days"
},
"remarks": [
"Fluorescence in situ hybridization (FISH), which detects the number of HER2 genes in the cancer cells:",
"https://ww5.komen.org/BreastCancer/TumorCharacteristics.html",
"",
"FISH results are usually available from the lab within a few days:",
"https://www.verywellhealth.com/fish-test-2252457"
],
"direct_transition": "Human_Epidermal_Growth_Factor_Receptor_2_HER2_Detection_Immunochemistry",
"reason": "breast_cancer_condition"
},
"HER2_negative": {
"type": "Observation",
"category": "laboratory",
"unit": "",
"codes": [
{
"system": "LOINC",
"code": "85319-2",
"display": "HER2 [Presence] in Breast cancer specimen by Immune stain"
}
],
"value_code": {
"system": "SNOMED-CT",
"code": "260385009",
"display": "Negative (qualifier value)"
},
"direct_transition": "HER2 ratio less than 1point8"
},
"HER2_positive": {
"type": "Observation",
"category": "laboratory",
"unit": "",
"codes": [
{
"system": "LOINC",
"code": "85319-2",
"display": "HER2 [Presence] in Breast cancer specimen by Immune stain"
}
],
"value_code": {
"system": "SNOMED-CT",
"code": "10828004",
"display": "Positive (qualifier value)"
},
"direct_transition": "HER2_ratio_greater_than_2point2"
},
"Tumor_Biopsy_to_Test_Estrogen_Receptor_Status": {
"type": "Simple",
"distributed_transition": [
{
"transition": "ER_negative",
"distribution": 0.2
},
{
"transition": "ER_positive",
"distribution": 0.8
}
],
"remarks": [
"About 80% of all breast cancers are “ER-positive.” That means the cancer cells grow in response to the hormone estrogen.:",
"https://www.webmd.com/breast-cancer/breast-cancer-types-er-positive-her2-positive#1"
]
},
"ER_negative": {
"type": "Observation",
"category": "laboratory",
"unit": "",
"codes": [
{
"system": "LOINC",
"code": "85337-4",
"display": "Estrogen receptor Ag [Presence] in Breast cancer specimen by Immune stain"
}
],
"value_code": {
"system": "SNOMED-CT",
"code": "260385009",
"display": "Negative (qualifier value)"
},
"direct_transition": "ER-"
},
"ER_positive": {
"type": "Observation",
"category": "laboratory",
"unit": "",
"codes": [
{
"system": "LOINC",
"code": "85337-4",
"display": "Estrogen receptor Ag [Presence] in Breast cancer specimen by Immune stain"
}
],
"value_code": {
"system": "SNOMED-CT",
"code": "10828004",
"display": "Positive (qualifier value)"
},
"direct_transition": "ER+"
},
"Tumor_Biopsy_to_Test_Progesterone_Receptor_Status": {
"type": "Simple",
"distributed_transition": [
{
"transition": "PR_negative",
"distribution": 0.35
},
{
"transition": "PR_positive",
"distribution": 0.65
}
],
"remarks": [
"About 80% of all breast cancers are “ER-positive.” That means the cancer cells grow in response to the hormone estrogen. About 65% of these are also “PR-positive.” They grow in response to another hormone, progesterone.:",
"https://www.webmd.com/breast-cancer/breast-cancer-types-er-positive-her2-positive#1"
]
},
"PR_negative": {
"type": "Observation",
"category": "laboratory",
"unit": "",
"codes": [
{
"system": "LOINC",
"code": "85339-0",
"display": "Progesterone receptor Ag [Presence] in Breast cancer specimen by Immune stain"
}
],
"value_code": {
"system": "SNOMED-CT",
"code": "260385009",
"display": "Negative (qualifier value)"
},
"direct_transition": "PR-"
},
"PR_positive": {
"type": "Observation",
"category": "laboratory",
"unit": "",
"codes": [
{
"system": "LOINC",
"code": "85339-0",
"display": "Progesterone receptor Ag [Presence] in Breast cancer specimen by Immune stain"
}
],
"value_code": {
"system": "SNOMED-CT",
"code": "10828004",
"display": "Positive (qualifier value)"
},
"direct_transition": "PR+"
},
"Overall_Receptor_Analysis": {
"type": "Simple",
"remarks": [
"If all hormones are negative transition to triple negative"
],
"conditional_transition": [
{
"transition": "Hormone Receptor Negative",
"condition": {
"condition_type": "And",
"conditions": [
{
"condition_type": "Attribute",
"attribute": "breast_cancer_ER",
"operator": "==",
"value": "ER-negative"
},
{
"condition_type": "Attribute",
"attribute": "breast_cancer_PR",
"operator": "==",
"value": "PR-negative"
}
]
}
},
{
"transition": "Hormone Receptor Positive",
"condition": {
"condition_type": "And",
"conditions": [
{
"condition_type": "Attribute",
"attribute": "breast_cancer_ER",
"operator": "==",
"value": "ER-positive"
},
{
"condition_type": "Attribute",
"attribute": "breast_cancer_PR",
"operator": "==",
"value": "PR-positive"
}
]
}
},
{
"transition": "Terminal"
}
]
},
"HER2-": {
"type": "SetAttribute",
"attribute": "breast_cancer_HER2",
"direct_transition": "Tumor_Biopsy_to_Test_Estrogen_Receptor_Status",
"value": "HER2-negative"
},
"HER2+": {
"type": "SetAttribute",
"attribute": "breast_cancer_HER2",
"value": "HER2-positive",
"direct_transition": "Tumor_Biopsy_to_Test_Estrogen_Receptor_Status"
},
"ER-": {
"type": "SetAttribute",
"attribute": "breast_cancer_ER",
"direct_transition": "Tumor_Biopsy_to_Test_Progesterone_Receptor_Status",
"value": "ER-negative"
},
"ER+": {
"type": "SetAttribute",
"attribute": "breast_cancer_ER",
"direct_transition": "Tumor_Biopsy_to_Test_Progesterone_Receptor_Status",
"value": "ER-positive"
},
"PR-": {
"type": "SetAttribute",
"attribute": "breast_cancer_PR",
"direct_transition": "Overall_Receptor_Analysis",
"value": "PR-negative"
},
"PR+": {
"type": "SetAttribute",
"attribute": "breast_cancer_PR",
"direct_transition": "Overall_Receptor_Analysis",
"value": "PR-positive"
},
"Triple_Negative": {
"type": "Observation",
"category": "laboratory",
"unit": "",
"codes": [
{
"system": "LOINC",
"code": "21924-6",
"display": "Tumor marker Cancer"
}
],
"value_code": {
"system": "SNOMED-CT",
"code": "260385009",
"display": "Negative (qualifier value)"
},
"direct_transition": "Triple_Negative_Patient",
"remarks": [
"In women with triple-negative breast cancer, the malignant cells do not contain receptors for estrogen, progesterone or HER2. Breast cancer that is ER-, PR- and HER2-negative cannot be treated with hormone therapy or medications that work by blocking HER2, such as trastuzumab."
]
},
"Hormone Receptor Positive": {
"type": "Observation",
"category": "laboratory",
"unit": "",
"codes": [
{
"system": "LOINC",
"code": "10480-2",
"display": "Estrogen+Progesterone receptor Ag [Presence] in Tissue by Immune stain"
}
],
"direct_transition": "Terminal",
"value_code": {
"system": "SNOMED-CT",
"code": "10828004",
"display": "Positive (qualifier value)"
},
"remarks": [
"Hormone receptor-positive (estrogen receptor-positive (ER-positive)/progesterone receptor-positive (PR-positive)) tumors express (have a lot of) hormone receptors.:",
"https://ww5.komen.org/BreastCancer/TumorCharacteristics.html"
]
},
"Hormone Receptor Negative": {
"type": "Observation",
"category": "laboratory",
"unit": "",
"codes": [
{
"system": "LOINC",
"code": "10480-2",
"display": "Estrogen+Progesterone receptor Ag [Presence] in Tissue by Immune stain"
}
],
"value_code": {
"system": "SNOMED-CT",
"code": "260385009",
"display": "Negative (qualifier value)"
},
"conditional_transition": [
{
"transition": "Triple_Negative",
"condition": {
"condition_type": "Attribute",
"attribute": "breast_cancer_HER2",
"operator": "==",
"value": "HER2-negative"
}
},
{
"transition": "Terminal"
}
],
"remarks": [
"Hormone receptor-negative (estrogen receptor-negative (ER-negative)/progesterone receptor-negative (PR- negative)) tumors do not express (have few or no) hormone receptors.:",
"https://ww5.komen.org/BreastCancer/TumorCharacteristics.html"
]
},
"Human_Epidermal_Growth_Factor_Receptor_2_HER2_Detection_Immunochemistry": {
"type": "Procedure",
"codes": [
{
"system": "SNOMED-CT",
"code": "433114000",
"display": "Human epidermal growth factor receptor 2 gene detection by immunohistochemistry (procedure)"
}
],
"duration": {
"low": 2,
"high": 4,
"unit": "hours"
},
"remarks": [
"Immunohistochemistry (IHC), which detects the number of HER2 protein receptors in the cancer cells:",
"https://ww5.komen.org/BreastCancer/TumorCharacteristics.html",
"",
"In about 20% of breast cancers, the cells make too much of a protein known as HER2. These cancers tend to be aggressive and fast-growing:",
"https://www.webmd.com/breast-cancer/breast-cancer-types-er-positive-her2-positive#1",
"",
"All antibody-antigen interactions investigated in this study, both the primary antibody binding to its target and the secondary antibody binding to the primary, require several hours to reach equilibrium at the concentrations used:",
"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3878317/"
],
"distributed_transition": [
{
"transition": "HER2_negative",
"distribution": 0.8
},
{
"transition": "HER2_positive",
"distribution": 0.2
}
],
"reason": "breast_cancer_condition"
},
"Triple_Negative_Patient": {
"type": "SetAttribute",
"attribute": "breast_cancer_triple_negative",
"direct_transition": "Terminal",
"value": true
},
"HER2 ratio less than 1point8": {
"type": "Observation",
"category": "laboratory",
"unit": "ratio",
"codes": [
{
"system": "LOINC",
"code": "85318-4",
"display": "HER2 [Presence] in Breast cancer specimen by FISH"
}
],
"direct_transition": "HER2-",
"remarks": [
"Title of the article: HER2 Evaluation and Its Impact on Breast Cancer Treatment Decisions",
"",
"https://wwwncbinlmnihgov/pmc/articles/PMC3225235/"
],
"exact": {
"quantity": "less than 1.8"
}
},
"HER2_ratio_greater_than_2point2": {
"type": "Observation",
"category": "laboratory",
"unit": "ratio",
"codes": [
{
"system": "LOINC",
"code": "85318-4",
"display": "HER2 [Presence] in Breast cancer specimen by FISH"
}
],
"direct_transition": "HER2+",
"remarks": [
"Title of the article: HER2 Evaluation and Its Impact on Breast Cancer Treatment Decisions",
"",
"https://wwwncbinlmnihgov/pmc/articles/PMC3225235/"
],
"exact": {
"quantity": "greater than 2.2"
}
}
},
"gmf_version": 1
}

View File

@@ -0,0 +1,544 @@
{
"name": "hormonetherapy_breast",
"remarks": [
"This module has ER/PR and HER2 treatments depending on whether each receptor is positive or negative. There is also treatment for if ER/PR are both positive. "
],
"states": {
"Initial": {
"type": "Initial",
"direct_transition": "ER-encounter"
},
"Fulvestrant": {
"type": "MedicationOrder",
"codes": [
{
"system": "RxNorm",
"code": 727762,
"display": "5 ML fulvestrant 50 MG/ML Prefilled Syringe"
}
],
"direct_transition": "ER_medication_end",
"assign_to_attribute": "ER_medication",
"remarks": [
"https://www.cancer.org/cancer/breast-cancer/treatment/hormone-therapy-for-breast-cancer.html",
"",
"Fulvestrant (Faslodex)",
"Fulvestrant is a drug that blocks and damages estrogen receptors.This drug is not a SERM it acts like an anti-estrogen throughout the body. It is also known as a selective estrogen receptor degrader (SERD).",
"",
"Fulvestrant is used to treat metastatic breast cancer, most often after other hormone drugs (like tamoxifen and often an aromatase inhibitor) have stopped working.",
"",
"It is given by injections into the buttocks. For the first month, the shots are given 2 weeks apart. After that, they are given once a month. Common short-term side effects can include:",
"",
"Hot flashes and/or night sweats",
"Headache",
"Mild nausea",
"Bone pain",
"Injection site pain",
"Because fulvestrant blocks estrogen, in theory it could cause weakened bones (osteoporosis) if taken for a long time. Fulvestrant is currently approved only for use in post-menopausal women. It is sometimes used “off-label” in pre-menopausal women, often combined with a luteinizing-hormone releasing hormone (LHRH) agonist to turn off the ovaries (see the section on Ovarian Ablation below)."
],
"reason": "breast_cancer_condition",
"administration": true
},
"Aromatase Inhibitors (AI)": {
"type": "SetAttribute",
"attribute": "breast_cancer_aromatase_inhibitors",
"distributed_transition": [
{
"transition": "Letrozole",
"distribution": 0.33
},
{
"transition": "Anastrozole",
"distribution": 0.33
},
{
"transition": "Exemestane",
"distribution": 0.34
}
],
"value": true,
"remarks": [
"https://www.cancer.org/cancer/breast-cancer/treatment/hormone-therapy-for-breast-cancer.html",
"",
"Aromatase inhibitors (AIs)",
"Aromatase inhibitors (AIs) are drugs that stop estrogen production. Before menopause, most estrogen is made by the ovaries. But for women whose ovaries arent working, either due to menopause or certain treatments, a small amount of estrogen is still made in the fat tissue by an enzyme (called aromatase). AIs work by blocking aromatase from making estrogen.",
"",
"These drugs are useful in women who are past menopause, although they can also be used in premenopausal women in combination with ovarian suppression (see below).",
"",
"There are 3 AIs that seem to work about equally well in treating breast cancer:",
"",
"Letrozole (Femara)",
"Anastrozole (Arimidex)",
"Exemestane (Aromasin)",
"These drugs are pills taken daily.",
"",
"Use in adjuvant therapy: After surgery, taking an AI, either alone or after tamoxifen, has been shown to work better than taking just tamoxifen for 5 years to reduce the risk of the cancer coming back .",
"",
"Schedules that are known to be helpful include:",
"",
"Tamoxifen for 2 to 3 years, followed by an AI to complete 5 years of treatment",
"An AI for 2 to 3 years followed by Tamoxifen to complete 5 years of treatment",
"Tamoxifen for 5 years, followed by an AI for 5 years",
"An AI for 5 years",
"Tamoxifen for 5 to 10 years (if you are unable to take an AI)",
"For most post-menopausal women whose cancers are hormone receptor-positive, most doctors recommend taking an AI at some point during adjuvant therapy. Right now, standard treatment is to take these drugs for about 5 years, or to alternate with tamoxifen for a total of at least 5 years, or to take in sequence with tamoxifen for at least 3 years. Studies are now being done to see if taking an AI for more than 5 years would be more helpful. Tamoxifen is an option for some women who cannot take an AI. Taking tamoxifen for 10 years is considered more effective than taking it for 5 years, but you and your doctor will decide the best schedule of treatment for you.",
"",
"If you have early-stage breast cancer and had not gone through menopause when you were first diagnosed, your doctor might recommend taking tamoxifen first, and then taking an AI later if you go through menopause during treatment. Another option is taking a drug called a luteinizing hormone-releasing hormone (LHRH) analog, which turns off the ovaries, along with an AI. An AI should not be taken alone for breast cancer treatment in pre-menopausal women because it is unsafe and can increase hormone levels.",
"",
"Use in cancer that comes back or has spread: AIs can also be used to treat more advanced hormone-positive breast cancers, especially in post-menopausal women. They are often continued for as long as they are helpful.",
"",
"Possible side effects: The AIs tend to have fewer serious side effects than tamoxifen. They don't cause uterine cancers and very rarely cause blood clots. They can, however, cause muscle pain and joint stiffness and/or pain. The joint pain may be similar to a feeling of having arthritis in many different joints at one time. Switching to a different AI may improve this side effect, but it has led some women to stop treatment. If this happens, most doctors recommend using tamoxifen to complete 5 to 10 years of hormone treatment.",
"",
"Because AIs drastically lower the estrogen level in women after menopause, they can also cause bone thinning, sometimes leading to osteoporosis and even fractures. If you are taking an AI, your bone density may be tested and you may also be given drugs, such as bisphosphonates or denosumab (Xgeva, Prolia), to strengthen your bones.",
"",
""
]
},
"Letrozole": {
"type": "MedicationOrder",
"codes": [
{
"system": "RxNorm",
"code": 200064,
"display": "letrozole 2.5 MG Oral Tablet"
}
],
"direct_transition": "ER_medication_end",
"assign_to_attribute": "ER_medication",
"prescription": {
"dosage": {
"amount": 1,
"frequency": 1,
"period": 1,
"unit": "days"
},
"duration": {
"quantity": 7,
"unit": "years"
}
},
"reason": "breast_cancer_condition",
"administration": true
},
"Anastrozole": {
"type": "MedicationOrder",
"codes": [
{
"system": "RxNorm",
"code": 199224,
"display": "anastrozole 1 MG Oral Tablet"
}
],
"direct_transition": "ER_medication_end",
"assign_to_attribute": "ER_medication",
"prescription": {
"dosage": {
"amount": 1,
"frequency": 1,
"period": 1,
"unit": "days"
},
"duration": {
"quantity": 7,
"unit": "years"
}
},
"reason": "breast_cancer_condition",
"administration": true
},
"Exemestane": {
"type": "MedicationOrder",
"codes": [
{
"system": "RxNorm",
"code": 310261,
"display": "exemestane 25 MG Oral Tablet"
}
],
"direct_transition": "ER_medication_end",
"assign_to_attribute": "ER_medication",
"prescription": {
"dosage": {
"amount": 1,
"frequency": 1,
"period": 1,
"unit": "days"
},
"duration": {
"quantity": 7,
"unit": "years"
}
},
"reason": "breast_cancer_condition",
"administration": true
},
"ER-Treatments": {
"type": "Simple",
"distributed_transition": [
{
"transition": "Estrogen Blocking Receptors",
"distribution": 0.6
},
{
"transition": "Fulvestrant",
"distribution": 0.1
},
{
"transition": "Aromatase Inhibitors (AI)",
"distribution": 0.3
}
],
"remarks": [
"https://www.breastcancer.org/research-news/5-more-years-of-ais-no-better-than-2-more",
""
]
},
"HER2-Treatment": {
"type": "Simple",
"remarks": [
"https://www.cancer.org/cancer/breast-cancer/treatment/targeted-therapy-for-breast-cancer.html",
"",
"For about 1 in 5 women with breast cancer, the cancer cells have too much of a growth-promoting protein known as HER2/neu (or just HER2) on their surface. These cancers, known as HER2-positive breast cancers, tend to grow and spread more aggressively. A number of drugs have been developed that target this protein:",
"",
"Trastuzumab (Herceptin): This is a monoclonal antibody, which is a man-made version of a very specific immune system protein. It is often given along with chemo, but it might also be used alone (especially if chemo alone has already been tried). Trastuzumab can be used to treat both early- and late-stage breast cancer. When started before or after surgery to treat early breast cancer, this drug is usually given for a total of 6 months to a year. For advanced breast cancer, treatment is often given for as long as the drug is helpful. This drug is given into a vein (IV) and is infused over 30-90 minutes. Another type of trastuzumab called trastuzumab and hyaluronidase-oysk injection (Herceptin Hylecta) is also available. It is given as a subcutaneous (under the skin) shot that takes about 2 to 5 minutes to inject.",
"Pertuzumab (Perjeta): This monoclonal antibody can be given with trastuzumab and chemo, either before surgery to treat early-stage breast cancer, or to treat advanced breast cancer. This drug is given into a vein (IV).",
"Ado-trastuzumab emtansine (Kadcyla, also known as TDM-1): This is a monoclonal antibody attached to a chemotherapy drug. It is used by itself to treat advanced breast cancer in women who have already been treated with trastuzumab and chemo. This drug is also given in a vein (IV).",
"Lapatinib (Tykerb): This is a kinase inhibitor. It is a pill taken daily. Lapatinib is used to treat advanced breast cancer, and might be used along with certain chemotherapy drugs, trastuzumab, or hormone therapy drugs.",
"Neratinib (Nerlynx): This is another kinase inhibitor. It is a pill that is taken daily. Neratinib is used to treat early-stage breast cancer after a woman has completed one year of trastuzumab and is usually given for one year. Some clinical trials show that it may also be effective in advanced breast cancer, as well.",
"Side effects of targeted therapy for HER2-positive breast cancer",
"The side effects of these drugs are often mild, but some can be serious. Discuss what you can expect with your doctor.",
"",
"Some women develop heart damage during or after treatment with trastuzumab, pertuzumab, or ado-trastuzumab emtansine. This can lead to congestive heart failure. For most (but not all) women, this effect lasts a short time and gets better when the drug is stopped. The risk of heart problems is higher when these drugs are given with certain chemo drugs that also can cause heart damage, such as doxorubicin (Adriamycin) and epirubicin (Ellence). Because these drugs can cause heart damage, doctors often check your heart function (with an echocardiogram or a MUGA scan) before treatment, and again while you are taking the drug. Let your doctor know if you develop symptoms such as shortness of breath, leg swelling, and severe fatigue.",
"",
"Lapatinib and neratinib can cause severe diarrhea, so its very important to let your health care team know about any changes in bowel habits as soon as they happen. Lapatinib can also cause hand-foot syndrome, in which the hands and feet become sore and red, and may blister and peel. Pertuzumab can also cause diarrhea. ",
"",
"If you are pregnant, you should not take these drugs. They can harm and even cause death to the fetus. If you could become pregnant, talk to your doctor about using effective birth control while taking these drugs.",
"",
"Targeted therapy for hormone receptor-positive breast cancer",
"About 2 of 3 breast cancers are hormone receptor-positive (ER-positive or PR-positive). For women with these cancers, treatment with hormone therapy is often helpful. Certain targeted therapy drugs can make hormone therapy even more effective, although these targeted drugs might also add to the side effects."
],
"complex_transition": [
{
"condition": {
"condition_type": "Attribute",
"attribute": "breast_cancer_HER2",
"operator": "==",
"value": "HER2-positive"
},
"distributions": [
{
"transition": "Trastuzumab_her2",
"distribution": 0.9
},
{
"transition": "Ado_trastuzumab_emtansine",
"distribution": 0.03
},
{
"transition": "Lapatinib",
"distribution": 0.03
},
{
"transition": "Neratinib",
"distribution": 0.04
}
]
},
{
"distributions": [
{
"distribution": 1,
"transition": "Hormone_Receptor_Positive_Treatments"
}
]
}
]
},
"Ado_trastuzumab_emtansine": {
"type": "MedicationOrder",
"codes": [
{
"system": "RxNorm",
"code": 1658084,
"display": "ado-trastuzumab emtansine 100 MG Injection"
}
],
"direct_transition": "HER2_medication_end",
"assign_to_attribute": "HER2_medication",
"reason": "breast_cancer_condition",
"administration": true
},
"Lapatinib": {
"type": "MedicationOrder",
"codes": [
{
"system": "RxNorm",
"code": 672149,
"display": "lapatinib 250 MG Oral Tablet"
}
],
"direct_transition": "HER2_medication_end",
"assign_to_attribute": "HER2_medication",
"reason": "breast_cancer_condition",
"administration": true
},
"Neratinib": {
"type": "MedicationOrder",
"codes": [
{
"system": "RxNorm",
"code": 1940648,
"display": "neratinib 40 MG Oral Tablet"
}
],
"direct_transition": "HER2_medication_end",
"assign_to_attribute": "HER2_medication",
"reason": "breast_cancer_condition",
"administration": true
},
"Trastuzumab_her2": {
"type": "MedicationOrder",
"codes": [
{
"system": "RxNorm",
"code": 2119714,
"display": "5 ML hyaluronidase-oysk 2000 UNT/ML / trastuzumab 120 MG/ML Injection"
}
],
"direct_transition": "HER2_medication_end",
"assign_to_attribute": "HER2_medication",
"reason": "breast_cancer_condition",
"administration": true
},
"CDK4/6 Inhibitors": {
"type": "Simple",
"distributed_transition": [
{
"transition": "Abemaciclib",
"distribution": 0.33
},
{
"transition": "Palbociclib",
"distribution": 0.33
},
{
"transition": "Ribociclib",
"distribution": 0.34
}
],
"remarks": [
"https://www.cancer.org/cancer/breast-cancer/treatment/targeted-therapy-for-breast-cancer.html",
"",
"CDK4/6 inhibitors",
"Palbociclib (Ibrance), ribociclib (Kisqali), and abemaciclib (Verzenio) are drugs that block proteins in the cell called cyclin-dependent kinases (CDKs), particularly CDK4 and CDK6. Blocking these proteins in hormone receptor-positive breast cancer cells helps stop the cells from dividing. This can slow cancer growth.",
"",
"These drugs are approved for women with advanced hormone receptor-positive, HER2-negative breast cancer and are taken as pills, typically once or twice a day.",
"",
"There are different ways to use these drugs.",
"",
"Any of the three drugs can be given along with an aromatase inhibitor (such as letrozole) or fulvestrant to women who have gone through menopause.",
"Palbociclib or abemaciclib can be given with fulvestrant to women who are still having regular periods (premenopausal) or are almost in menopause (perimenopausal). These women, however, must also be on medicines, such as luteinizing hormone-releasing hormone (LHRH) analogs, that stop the ovaries from making estrogen.",
"Ribociclib can be given with an aromatase inhibitor to women who have not gone through menopause. Again, these women must also be on medicines that suppress the ovaries, such as a luteinizing hormone-releasing hormone (LHRH) analogs. ",
"Abemaciclib can also be used by itself in women who have previously been treated with hormone therapy and chemotherapy.",
"",
"Side effects of these drugs tend to be mild. The most common side effects are low blood cell counts and fatigue. Nausea and vomiting, mouth sores, hair loss, diarrhea, and headache are less common side effects. Very low white blood cell counts can increase the risk of serious infection.",
"",
""
]
},
"Abemaciclib": {
"type": "MedicationOrder",
"codes": [
{
"system": "RxNorm",
"code": 1946840,
"display": "Verzenio 100 MG Oral Tablet"
}
],
"direct_transition": "ER_PR_medication_end",
"assign_to_attribute": "ER_PR_medication",
"reason": "breast_cancer_condition",
"administration": true
},
"Palbociclib": {
"type": "MedicationOrder",
"codes": [
{
"system": "RxNorm",
"code": 1601380,
"display": "palbociclib 100 MG Oral Capsule"
}
],
"direct_transition": "ER_PR_medication_end",
"assign_to_attribute": "ER_PR_medication",
"reason": "breast_cancer_condition",
"administration": true
},
"Ribociclib": {
"type": "MedicationOrder",
"codes": [
{
"system": "RxNorm",
"code": 1873983,
"display": "ribociclib 200 MG Oral Tablet"
}
],
"direct_transition": "ER_PR_medication_end",
"assign_to_attribute": "ER_PR_medication",
"reason": "breast_cancer_condition",
"administration": true
},
"ER-encounter": {
"type": "Encounter",
"encounter_class": "ambulatory",
"reason": "breast_cancer_condition",
"codes": [
{
"system": "SNOMED-CT",
"code": "185347001",
"display": "Encounter for problem (procedure)"
}
],
"conditional_transition": [
{
"transition": "ER-Treatments",
"condition": {
"condition_type": "Or",
"conditions": [
{
"condition_type": "Attribute",
"attribute": "breast_cancer_PR",
"operator": "==",
"value": "PR-positive"
},
{
"condition_type": "Attribute",
"attribute": "breast_cancer_ER",
"operator": "==",
"value": "ER-positive"
}
]
}
},
{
"transition": "Upper Stage Treatment"
}
]
},
"Upper Stage Treatment": {
"type": "Simple",
"direct_transition": "HER2-Treatment"
},
"Terminal": {
"type": "Terminal"
},
"end_encounter": {
"type": "EncounterEnd",
"direct_transition": "Terminal"
},
"Hormone_Receptor_Positive_Treatments": {
"type": "Simple",
"conditional_transition": [
{
"transition": "CDK4/6 Inhibitors",
"condition": {
"condition_type": "And",
"conditions": [
{
"condition_type": "Attribute",
"attribute": "breast_cancer_ER",
"operator": "==",
"value": "ER-positive"
},
{
"condition_type": "Attribute",
"attribute": "breast_cancer_PR",
"operator": "==",
"value": "PR-positive"
}
]
}
},
{
"transition": "end_encounter"
}
]
},
"Tamoxifen": {
"type": "MedicationOrder",
"codes": [
{
"system": "RxNorm",
"code": 198240,
"display": "Tamoxifen 10 MG Oral Tablet"
}
],
"direct_transition": "ER_medication_end",
"assign_to_attribute": "ER_medication",
"prescription": {
"dosage": {
"amount": 1,
"frequency": 1,
"period": 1,
"unit": "days"
},
"duration": {
"quantity": 10,
"unit": "years"
}
},
"reason": "breast_cancer_condition",
"administration": true
},
"Estrogen Blocking Receptors": {
"type": "SetAttribute",
"attribute": "breast_cancer_tamoxifen",
"direct_transition": "Tamoxifen",
"value": true,
"remarks": [
"https://www.cancer.org/cancer/breast-cancer/treatment/hormone-therapy-for-breast-cancer.html",
"",
"Tamoxifen",
"This drug blocks estrogen receptors on breast cancer cells. It stops estrogen from connecting to the cancer cells and telling them to grow and divide. While tamoxifen acts like an anti-estrogen in breast cells, it acts like an estrogen in other tissues, like the uterus and the bones. Because of this, it is called a selective estrogen receptor modulator (SERM).",
"",
"Tamoxifen can be used in several ways:",
"",
"For women with hormone receptor-positive breast cancer treated with surgery, tamoxifen can help lower the chances of the cancer coming back and raise the chances of living longer. It can also lower the risk of getting a new cancer in the other breast. Tamoxifen can be started either after surgery (adjuvant therapy) or before surgery (neoadjuvant therapy) and is usually taken for 5 to 10 years. For early- stage breast cancer, this drug is mainly used for women who have not yet gone through menopause. (If you have gone through menopause, aromatase inhibitors are usually used instead.)",
"For women who have been treated for ductal carcinoma in situ (DCIS) that is hormone receptor-positive, taking tamoxifen for 5 years lowers the chance of the DCIS coming back. It also lowers the chance of getting an invasive breast cancer.",
"For women with hormone-positive breast cancer that has spread to other parts of the body, tamoxifen can often help slow or stop the growth of the cancer, and might even shrink some tumors.",
"In women at high risk of breast cancer, tamoxifen can be used to help lower the risk of developing breast cancer.",
"Toremifene (Fareston) is another SERM that works in a similar way, but it is used less often and is only approved to treat metastatic breast cancer. It is not likely to work if tamoxifen has already been used and has stopped working. These drugs are taken by mouth as a pill. The most common side effects of tamoxifen and toremifene are:",
"",
"Hot flashes",
"Vaginal dryness or discharge",
"Mood swings",
"Some women with cancer spread to the bones may have a tumor flare with pain and swelling in the muscles and bones. This usually decreases quickly, but in some rare cases a woman may also develop a high calcium level in the blood that is hard to control. If this happens, the treatment may need to be stopped for a time.",
"",
"Rare, but more serious side effects are also possible:",
"",
"If a woman has gone through menopause, these drugs can increase her risk of developing uterine cancer . Tell your doctor right away about any unusual vaginal bleeding (a common symptom of both of these cancers). Most uterine bleeding is not from cancer, but this symptom always needs prompt attention.",
"Blood clots are another uncommon, but serious side effect. They usually form in the legs (called deep vein thrombosis or DVT), but sometimes a piece of clot may break off and end up blocking an artery in the lungs (pulmonary embolism or PE). Call your doctor or nurse right away if you develop pain, redness, or swelling in your lower leg (calf), shortness of breath, or chest pain, because these can be symptoms of a DVT or PE.",
"Rarely, tamoxifen has been associated with strokes in post-menopausal women, so tell your doctor if you have severe headaches, confusion, or trouble speaking or moving.",
"Depending on a woman's menopausal status, tamoxifen can have different effects on the bones. In pre-menopausal women, tamoxifen can cause some bone thinning, but in post-menopausal women it is often good to strengthen bone. The benefits of taking these drugs outweigh the risks for almost all women with hormone receptor-positive breast cancer.",
"",
""
]
},
"ER_medication_end": {
"type": "MedicationEnd",
"direct_transition": "Upper Stage Treatment",
"referenced_by_attribute": "ER_medication"
},
"HER2_medication_end": {
"type": "MedicationEnd",
"direct_transition": "Hormone_Receptor_Positive_Treatments",
"referenced_by_attribute": "HER2_medication"
},
"ER_PR_medication_end": {
"type": "MedicationEnd",
"referenced_by_attribute": "ER_PR_medication",
"direct_transition": "end_encounter"
}
},
"gmf_version": 1
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,657 @@
{
"name": "TNM_Diagnosis",
"remarks": [
"This module goes through and diagnoses which T, N, and M stage a person would encounter through the screening. "
],
"states": {
"Initial": {
"type": "Initial",
"direct_transition": "M Marker"
},
"Terminal": {
"type": "Terminal"
},
"M Marker": {
"type": "Simple",
"distributed_transition": [
{
"transition": "No Evidence of Distant Metastasis ",
"distribution": 0.94
},
{
"transition": "Distant Metastases Detected",
"distribution": 0.06
}
],
"remarks": [
"About 6% of women have metastatic cancer when they are first diagnosed with breast cancer:",
"https://www.cancer.net/cancer-types/breast-cancer/statistics"
]
},
"N Marker": {
"type": "Simple",
"complex_transition": [
{
"condition": {
"condition_type": "Attribute",
"attribute": "breast_cancer_Location",
"operator": "==",
"value": "local"
},
"transition": "No Regional Lymph Node Metastasis"
},
{
"distributions": [
{
"distribution": 0.34,
"transition": "Micrometastasis in 1 - 3 Lymph Nodes"
},
{
"distribution": 0.33,
"transition": "Macrometastases in 4 - 9 Lymph Nodes"
},
{
"distribution": 0.33,
"transition": "Macrometastases in 10+ Lymph Nodes"
}
],
"condition": {
"condition_type": "Attribute",
"attribute": "breast_cancer_M",
"operator": "==",
"value": "M1"
}
},
{
"distributions": [
{
"transition": "Micrometastasis in 1 - 3 Lymph Nodes",
"distribution": 0.6
},
{
"transition": "Macrometastases in 4 - 9 Lymph Nodes",
"distribution": 0.3
},
{
"transition": "Macrometastases in 10+ Lymph Nodes",
"distribution": 0.10000000000000009
}
],
"condition": {
"condition_type": "Attribute",
"attribute": "breast_cancer_Location",
"operator": "==",
"value": "regional"
}
}
],
"remarks": [
"Lymph node status shows whether or not the lymph nodes in the underarm area (axillary lymph nodes) contain cancer:",
"Lymph node-negative means the axillary lymph nodes do not contain cancer.",
"Lymph node-positive means the axillary lymph nodes contain cancer.",
"Prognosis is better when cancer has not spread to the lymph nodes (lymph node-negative) [13].",
"The more lymph nodes that contain cancer, the poorer prognosis tends to be [13].",
"The number of positive nodes guides treatment and helps predict prognosis (chances for survival).",
"See Figure 4.4 for an illustration of the breast and lymph nodes.",
"https://ww5.komen.org/BreastCancer/LymphNodeStatusandStaging.html"
]
},
"T4": {
"type": "SetAttribute",
"attribute": "breast_cancer_T",
"direct_transition": "T4_Diagnosed",
"value": "T4",
"remarks": [
"AJCC Cancer Staging Manual; 8th Edition"
]
},
"N1": {
"type": "SetAttribute",
"attribute": "breast_cancer_N",
"direct_transition": "N1_Diagnosed",
"value": "N1"
},
"N2": {
"type": "SetAttribute",
"attribute": "breast_cancer_N",
"direct_transition": "N2_Diagnosed",
"value": "N2"
},
"N3": {
"type": "SetAttribute",
"attribute": "breast_cancer_N",
"direct_transition": "N3_Diagnosed",
"value": "N3"
},
"Distant Breast Cancer": {
"type": "SetAttribute",
"attribute": "breast_cancer_Location",
"direct_transition": "Tumor Size Any",
"value": "distant"
},
"Regional Breast Cancer": {
"type": "SetAttribute",
"attribute": "breast_cancer_Location",
"distributed_transition": [
{
"transition": "Tumor Size Less than 2 cm",
"distribution": 0.3011
},
{
"transition": "Tumor Size 2 -5 cm",
"distribution": 0.5053
},
{
"transition": "Tumor Size Greater Than 5 cm",
"distribution": 0.1398
},
{
"transition": "No Evidence of Primary Tumor in Breast",
"distribution": 0.0538
}
],
"remarks": [
"Adjusted Tumor Data for Regional Breast Cancer:",
"https://onlinelibrary.wiley.com/doi/full/10.1002/cncr.21285"
],
"value": "regional"
},
"Local Breast Cancer": {
"type": "SetAttribute",
"attribute": "breast_cancer_Location",
"distributed_transition": [
{
"transition": "Tumor Size Less than 2 cm",
"distribution": 0.7052
},
{
"transition": "Tumor Size 2 -5 cm",
"distribution": 0.2632
},
{
"transition": "Tumor Size Greater Than 5 cm",
"distribution": 0.0316
}
],
"remarks": [
"Adjusted Tumor Data for Local Breast Cancer:",
"https://onlinelibrary.wiley.com/doi/full/10.1002/cncr.21285"
],
"value": "local"
},
"M1_Diagnosed": {
"type": "Observation",
"category": "imaging",
"unit": "",
"codes": [
{
"system": "LOINC",
"code": "21907-1",
"display": "Distant metastases.clinical [Class] Cancer"
}
],
"value_code": {
"system": "SNOMED-CT",
"code": 55440008,
"display": "M1 category (finding)"
},
"direct_transition": "Distant Breast Cancer"
},
"M0_Diagnosed": {
"type": "Observation",
"category": "imaging",
"unit": "",
"codes": [
{
"system": "LOINC",
"code": "21907-1",
"display": "Distant metastases.clinical [Class] Cancer"
}
],
"value_code": {
"system": "SNOMED-CT",
"code": 30893008,
"display": "M0 category (finding)"
},
"distributed_transition": [
{
"transition": "Local Breast Cancer",
"distribution": 0.62
},
{
"transition": "Regional Breast Cancer",
"distribution": 0.38
}
],
"remarks": [
"If the cancer is located only in the breast, the 5-year survival rate of women with breast cancer is 99%. Sixty-two percent (62%) of cases are diagnosed at this stage:",
"https://www.cancer.net/cancer-types/breast-cancer/statistics"
]
},
"T0_Diagnosed": {
"type": "Observation",
"category": "imaging",
"unit": "",
"codes": [
{
"system": "LOINC",
"code": "21905-5",
"display": "Primary tumor.clinical [Class] Cancer"
}
],
"direct_transition": "N Marker",
"value_code": {
"system": "SNOMED-CT",
"code": 58790005,
"display": "T0 category (finding)"
}
},
"T1_Diagnosed": {
"type": "Observation",
"category": "imaging",
"unit": "",
"codes": [
{
"system": "LOINC",
"code": "21905-5",
"display": "Primary tumor.clinical [Class] Cancer"
}
],
"value_code": {
"system": "SNOMED-CT",
"code": 23351008,
"display": "T1 category (finding)"
},
"direct_transition": "N Marker"
},
"T2_Diagnosed": {
"type": "Observation",
"category": "imaging",
"unit": "",
"codes": [
{
"system": "LOINC",
"code": "21905-5",
"display": "Primary tumor.clinical [Class] Cancer"
}
],
"value_code": {
"system": "SNOMED-CT",
"code": 67673008,
"display": "T2 category (finding)"
},
"direct_transition": "N Marker"
},
"T3_Diagnosed": {
"type": "Observation",
"category": "imaging",
"unit": "",
"codes": [
{
"system": "LOINC",
"code": "21905-5",
"display": "Primary tumor.clinical [Class] Cancer"
}
],
"value_code": {
"system": "SNOMED-CT",
"code": 14410001,
"display": "T3 category (finding)"
},
"direct_transition": "N Marker",
"remarks": [
"https://www.cancer.net/cancer-types/breast-cancer/statistics"
]
},
"T4_Diagnosed": {
"type": "Observation",
"category": "imaging",
"unit": "",
"codes": [
{
"system": "LOINC",
"code": "21905-5",
"display": "Primary tumor.clinical [Class] Cancer"
}
],
"value_code": {
"system": "SNOMED-CT",
"code": 65565005,
"display": "T4 category (finding)"
},
"direct_transition": "N Marker"
},
"N1_Diagnosed": {
"type": "Observation",
"category": "imaging",
"unit": "",
"codes": [
{
"system": "LOINC",
"code": "21906-3",
"display": "Regional lymph nodes.clinical [Class] Cancer"
}
],
"direct_transition": "Terminal",
"value_code": {
"system": "SNOMED-CT",
"code": 53623008,
"display": "N1 category (finding)"
}
},
"N0_Diagnosed": {
"type": "Observation",
"category": "imaging",
"unit": "",
"codes": [
{
"system": "LOINC",
"code": "21906-3",
"display": "Regional lymph nodes.clinical [Class] Cancer"
}
],
"value_code": {
"system": "SNOMED-CT",
"code": 62455006,
"display": "N0 category (finding)"
},
"direct_transition": "Terminal"
},
"N2_Diagnosed": {
"type": "Observation",
"category": "imaging",
"unit": "",
"codes": [
{
"system": "LOINC",
"code": "21906-3",
"display": "Regional lymph nodes.clinical [Class] Cancer"
}
],
"value_code": {
"system": "SNOMED-CT",
"code": 46059003,
"display": "N2 category (finding)"
},
"direct_transition": "Terminal"
},
"N3_Diagnosed": {
"type": "Observation",
"category": "imaging",
"unit": "",
"codes": [
{
"system": "LOINC",
"code": "21906-3",
"display": "Regional lymph nodes.clinical [Class] Cancer"
}
],
"value_code": {
"system": "SNOMED-CT",
"code": 5856006,
"display": "N3 category (finding)"
},
"direct_transition": "Terminal"
},
"T1": {
"type": "SetAttribute",
"attribute": "breast_cancer_T",
"value": "T1",
"direct_transition": "T1_Diagnosed",
"remarks": [
"AJCC Cancer Staging Manual; 8th Edition"
]
},
"No Evidence of Primary Tumor in Breast": {
"type": "Simple",
"direct_transition": "T0",
"remarks": [
"AJCC Cancer Staging Manual; 8th Edition"
]
},
"T0": {
"type": "SetAttribute",
"attribute": "breast_cancer_T",
"value": "T0",
"direct_transition": "T0_Diagnosed"
},
"Tumor Size 2 -5 cm": {
"type": "Observation",
"category": "imaging",
"unit": "cm",
"codes": [
{
"system": "LOINC",
"code": "33728-7",
"display": "Size.maximum dimension in Tumor"
}
],
"direct_transition": "T2",
"remarks": [
"AJCC Cancer Staging Manual; 8th Edition"
],
"range": {
"low": 2,
"high": 5
}
},
"T2": {
"type": "SetAttribute",
"attribute": "breast_cancer_T",
"value": "T2",
"direct_transition": "T2_Diagnosed",
"remarks": [
"AJCC Cancer Staging Manual; 8th Edition"
]
},
"Tumor Size Greater Than 5 cm": {
"type": "Observation",
"category": "imaging",
"unit": "cm",
"codes": [
{
"system": "LOINC",
"code": "33728-7",
"display": "Size.maximum dimension in Tumor"
}
],
"direct_transition": "T3",
"remarks": [
"AJCC Cancer Staging Manual; 8th Edition"
],
"range": {
"low": 5,
"high": 6
}
},
"Tumor Size Less than 2 cm": {
"type": "Observation",
"category": "imaging",
"unit": "cm",
"codes": [
{
"system": "LOINC",
"code": "33728-7",
"display": "Size.maximum dimension in Tumor"
}
],
"direct_transition": "T1",
"range": {
"low": 0,
"high": 2
},
"remarks": [
"AJCC Cancer Staging Manual; 8th Edition"
]
},
"T3": {
"type": "SetAttribute",
"attribute": "breast_cancer_T",
"value": "T3",
"direct_transition": "T3_Diagnosed",
"remarks": [
"AJCC Cancer Staging Manual; 8th Edition"
]
},
"Tumor Size Any": {
"type": "Observation",
"category": "imaging",
"unit": "cm",
"codes": [
{
"system": "LOINC",
"code": "33728-7",
"display": "Size.maximum dimension in Tumor"
}
],
"remarks": [
"AJCC Cancer Staging Manual; 8th Edition"
],
"range": {
"low": 0,
"high": 6
},
"direct_transition": "T4"
},
"No Evidence of Distant Metastasis ": {
"type": "Observation",
"category": "imaging",
"unit": "",
"codes": [
{
"system": "LOINC",
"code": "44667-4",
"display": "Site of distant metastasis in Breast tumor"
}
],
"direct_transition": "M0",
"remarks": [
"https://www.cancer.net/cancer-types/breast-cancer/statistics",
"AJCC Cancer Staging Manual; 8th Edition"
],
"value_code": {
"system": "SNOMED-CT",
"code": "260413007",
"display": "None (qualifier value)"
}
},
"M0": {
"type": "SetAttribute",
"attribute": "breast_cancer_M",
"value": "M0",
"remarks": [
"AJCC Cancer Staging Manual; 8th Edition",
"Cancer has either spread beyond the breast and nearby lymph nodes to other areas of the body (M1) or it has not (MO):",
"https://ww5.komen.org/BreastCancer/MetastasesandStaging.html"
],
"direct_transition": "M0_Diagnosed"
},
"Distant Metastases Detected": {
"type": "Simple",
"direct_transition": "M1",
"remarks": [
"AJCC Cancer Staging Manual; 8th Edition"
]
},
"M1": {
"type": "SetAttribute",
"attribute": "breast_cancer_M",
"value": "M1",
"direct_transition": "M1_Diagnosed",
"remarks": [
"AJCC Cancer Staging Manual; 8th Edition"
]
},
"No Regional Lymph Node Metastasis": {
"type": "Observation",
"category": "imaging",
"unit": "{#}",
"codes": [
{
"system": "LOINC",
"code": "85352-3",
"display": "Lymph nodes with isolated tumor cells [#] in Cancer specimen by Light microscopy"
}
],
"exact": {
"quantity": 0
},
"direct_transition": "N0",
"remarks": [
"AJCC Cancer Staging Manual; 8th Edition",
"https://ww5.komen.org/BreastCancer/LymphNodeStatusandStaging.html"
]
},
"N0": {
"type": "SetAttribute",
"attribute": "breast_cancer_N",
"value": "N0",
"direct_transition": "N0_Diagnosed"
},
"Micrometastasis in 1 - 3 Lymph Nodes": {
"type": "Observation",
"category": "imaging",
"unit": "{#}",
"codes": [
{
"system": "LOINC",
"code": "85344-0",
"display": "Lymph nodes with micrometastases [#] in Cancer specimen by Light microscopy"
}
],
"direct_transition": "N1",
"range": {
"low": 1,
"high": 3
},
"remarks": [
"AJCC Cancer Staging Manual; 8th Edition",
"https://ww5.komen.org/BreastCancer/LymphNodeStatusandStaging.html"
]
},
"Macrometastases in 4 - 9 Lymph Nodes": {
"type": "Observation",
"category": "imaging",
"unit": "{#}",
"codes": [
{
"system": "LOINC",
"code": "85343-2",
"display": "Lymph nodes with macrometastases [#] in Cancer specimen by Light microscopy"
}
],
"direct_transition": "N2",
"range": {
"low": 4,
"high": 9
},
"remarks": [
"AJCC Cancer Staging Manual; 8th Edition",
"https://ww5.komen.org/BreastCancer/LymphNodeStatusandStaging.html"
]
},
"Macrometastases in 10+ Lymph Nodes": {
"type": "Observation",
"category": "imaging",
"unit": "{#}",
"codes": [
{
"system": "LOINC",
"code": "85343-2",
"display": "Lymph nodes with macrometastases [#] in Cancer specimen by Light microscopy"
}
],
"direct_transition": "N3",
"range": {
"low": 10,
"high": 30
},
"remarks": [
"AJCC Cancer Staging Manual; 8th Edition",
"https://ww5.komen.org/BreastCancer/LymphNodeStatusandStaging.html",
"https://www.medicalnewstoday.com/articles/319713.php"
]
}
},
"gmf_version": 1
}

View File

@@ -0,0 +1,541 @@
{
"name": "Bronchitis",
"remarks": [
"For now this covers only acute bronchitis. Chronic bronchitis is one of the conditions included in chronic obstructive pulmonary disease (COPD).",
"Acute bronchitis is the fifth most common reason why adults see their GP; 5% of the adult population seeks medical advice for bronchitis each year.",
"Most of the data here comes from the following sources: ",
"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC2278319/",
"http://www.aafp.org/afp/1998/0315/p1270.html"
],
"states": {
"Initial": {
"type": "Initial",
"direct_transition": "Potential_Infection"
},
"Potential_Infection": {
"type": "Delay",
"exact": {
"quantity": 1,
"unit": "months"
},
"complex_transition": [
{
"condition": {
"condition_type": "Age",
"operator": "<",
"quantity": 18,
"unit": "years"
},
"distributions": [
{
"distribution": 0.005,
"transition": "Bronchitis_Infection",
"remarks": [
"6% of children get bronchitis each year.",
"6% / year == ~ .5% per month?"
]
},
{
"distribution": 0.995,
"transition": "Potential_Infection"
}
]
},
{
"distributions": [
{
"distribution": 0.00416,
"transition": "Bronchitis_Infection",
"remarks": [
"5% of the adult population seeks medical advice for bronchitis each year.",
"5% / year == ~ .42% per month?"
]
},
{
"distribution": 0.99584,
"transition": "Potential_Infection"
}
]
}
]
},
"Bronchitis_Infection": {
"type": "ConditionOnset",
"target_encounter": "Doctor_Visit",
"codes": [
{
"system": "SNOMED-CT",
"code": "10509002",
"display": "Acute bronchitis (disorder)"
}
],
"direct_transition": "Bronchitis_Symptom1"
},
"Bronchitis_Symptom1": {
"type": "Symptom",
"symptom": "Cough",
"range": {
"low": 25,
"high": 75
},
"direct_transition": "Bronchitis_Symptom2"
},
"Bronchitis_Symptom2": {
"type": "Symptom",
"symptom": "Mucus",
"range": {
"low": 25,
"high": 50
},
"direct_transition": "Bronchitis_Symptom3"
},
"Bronchitis_Symptom3": {
"type": "Symptom",
"symptom": "Shortness of Breath",
"range": {
"low": 25,
"high": 75
},
"direct_transition": "Bronchitis_Symptom4"
},
"Bronchitis_Symptom4": {
"type": "Symptom",
"symptom": "Sore Throat",
"range": {
"low": 25,
"high": 50
},
"direct_transition": "Bronchitis_Symptom5"
},
"Bronchitis_Symptom5": {
"type": "Symptom",
"symptom": "Fatigue",
"range": {
"low": 25,
"high": 75
},
"direct_transition": "Bronchitis_Symptom6"
},
"Bronchitis_Symptom6": {
"type": "Symptom",
"symptom": "Fever",
"range": {
"low": 25,
"high": 50
},
"direct_transition": "Bronchitis_Symptom7"
},
"Bronchitis_Symptom7": {
"type": "Symptom",
"symptom": "Body Aches",
"range": {
"low": 0,
"high": 25
},
"direct_transition": "Bronchitis_Symptom8"
},
"Bronchitis_Symptom8": {
"type": "Symptom",
"symptom": "Nasal Congestion",
"range": {
"low": 25,
"high": 50
},
"direct_transition": "Bronchitis_Symptom9"
},
"Bronchitis_Symptom9": {
"type": "Symptom",
"symptom": "Nausea/Vomiting",
"range": {
"low": 0,
"high": 25
},
"direct_transition": "Bronchitis_Symptom10"
},
"Bronchitis_Symptom10": {
"type": "Symptom",
"symptom": "Diarrhea",
"range": {
"low": 0,
"high": 25
},
"direct_transition": "Symptoms_Dont_improve"
},
"Symptoms_Dont_improve": {
"type": "Delay",
"range": {
"low": 1,
"high": 3,
"unit": "days"
},
"direct_transition": "Doctor_Visit"
},
"Doctor_Visit": {
"type": "Encounter",
"encounter_class": "ambulatory",
"reason": "Bronchitis_Infection",
"remarks": [
"There are no reliable diagnostic signs or laboratory tests, so the diagnosis of acute bronchitis is essentially a clinical one. ",
"The most important condition to rule out is acute pneumonia. "
],
"codes": [
{
"system": "SNOMED-CT",
"code": "185345009",
"display": "Encounter for symptom (procedure)"
}
],
"distributed_transition": [
{
"distribution": 0.05,
"transition": "Chest_Xray"
},
{
"distribution": 0.2,
"transition": "Sputum_Test"
},
{
"distribution": 0.5,
"transition": "Lung_Function_Test"
},
{
"distribution": 0.2,
"transition": "Bronchitis_CarePlan_Selector"
}
]
},
"Chest_Xray": {
"type": "Procedure",
"reason": "Bronchitis_Infection",
"codes": [
{
"system": "SNOMED-CT",
"code": "399208008",
"display": "Plain X-ray of chest (procedure)"
}
],
"duration": {
"low": 10,
"high": 25,
"unit": "minutes"
},
"direct_transition": "Bronchitis_CarePlan_Selector"
},
"Sputum_Test": {
"type": "Procedure",
"reason": "Bronchitis_Infection",
"codes": [
{
"system": "SNOMED-CT",
"code": "269911007",
"display": "Sputum examination (procedure)"
}
],
"duration": {
"low": 3,
"high": 15,
"unit": "minutes"
},
"direct_transition": "Bronchitis_CarePlan_Selector"
},
"Lung_Function_Test": {
"type": "Procedure",
"reason": "Bronchitis_Infection",
"codes": [
{
"system": "SNOMED-CT",
"code": "23426006",
"display": "Measurement of respiratory function (procedure)"
}
],
"duration": {
"low": 10,
"high": 25,
"unit": "minutes"
},
"direct_transition": "Bronchitis_CarePlan_Selector"
},
"Bronchitis_CarePlan_Selector": {
"type": "Simple",
"conditional_transition": [
{
"condition": {
"condition_type": "And",
"conditions": [
{
"condition_type": "Age",
"operator": ">=",
"quantity": 18,
"unit": "years"
},
{
"condition_type": "Attribute",
"attribute": "smoker",
"operator": "==",
"value": true
}
]
},
"transition": "Smoker_CarePlan"
},
{
"transition": "Nonsmoker_CarePlan"
}
]
},
"Smoker_CarePlan": {
"type": "CarePlanStart",
"assign_to_attribute": "bronchitis_careplan",
"reason": "Bronchitis_Infection",
"codes": [
{
"system": "SNOMED-CT",
"code": "53950000",
"display": "Respiratory therapy (procedure)"
}
],
"activities": [
{
"system": "SNOMED-CT",
"code": "710081004",
"display": "Smoking cessation therapy (regime/therapy)"
},
{
"system": "SNOMED-CT",
"code": "304510005",
"display": "Recommendation to avoid exercise (procedure)"
},
{
"system": "SNOMED-CT",
"code": "371605008",
"display": "Deep breathing and coughing exercises (regime/therapy)"
}
],
"direct_transition": "OTC_Medicine"
},
"Nonsmoker_CarePlan": {
"type": "CarePlanStart",
"assign_to_attribute": "bronchitis_careplan",
"reason": "Bronchitis_Infection",
"codes": [
{
"system": "SNOMED-CT",
"code": "53950000",
"display": "Respiratory therapy (procedure)"
}
],
"activities": [
{
"system": "SNOMED-CT",
"code": "304510005",
"display": "Recommendation to avoid exercise (procedure)"
},
{
"system": "SNOMED-CT",
"code": "371605008",
"display": "Deep breathing and coughing exercises (regime/therapy)"
}
],
"direct_transition": "OTC_Medicine"
},
"OTC_Medicine": {
"type": "Simple",
"remarks": [
"Up to 95% of bronchitis cases are viral so antibiotics are rarely prescribed",
"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC2278319/"
],
"complex_transition": [
{
"condition": {
"condition_type": "Symptom",
"symptom": "Mucus",
"operator": "<",
"value": 30
},
"distributions": [
{
"distribution": 0.8,
"transition": "Cough_suppressant"
},
{
"distribution": 0.2,
"transition": "Acetaminophen"
}
],
"remarks": [
"cough suppressants shouldn't be given if the cough brings up mucus"
]
},
{
"distributions": [
{
"distribution": 0.1,
"transition": "Cough_suppressant"
},
{
"distribution": 0.9,
"transition": "Acetaminophen"
}
]
}
]
},
"Cough_suppressant": {
"type": "MedicationOrder",
"assign_to_attribute": "OTC_Bronchitis_Med",
"reason": "Bronchitis_Infection",
"codes": [
{
"system": "RxNorm",
"code": "1043400",
"display": "Acetaminophen 21.7 MG/ML / Dextromethorphan Hydrobromide 1 MG/ML / doxylamine succinate 0.417 MG/ML Oral Solution"
}
],
"direct_transition": "End_Doctor_Visit"
},
"Acetaminophen": {
"type": "MedicationOrder",
"assign_to_attribute": "OTC_Bronchitis_Med",
"reason": "Bronchitis_Infection",
"codes": [
{
"system": "RxNorm",
"code": "313782",
"display": "Acetaminophen 325 MG Oral Tablet"
}
],
"direct_transition": "End_Doctor_Visit"
},
"End_Doctor_Visit": {
"type": "EncounterEnd",
"direct_transition": "Wait_for_condition_to_resolve"
},
"Wait_for_condition_to_resolve": {
"type": "Delay",
"range": {
"low": 1,
"high": 3,
"unit": "weeks"
},
"direct_transition": "Bronchitis_Subsides"
},
"Bronchitis_Subsides": {
"type": "ConditionEnd",
"condition_onset": "Bronchitis_Infection",
"direct_transition": "Bronchitis_Symptom1_Subsides"
},
"Bronchitis_Symptom1_Subsides": {
"type": "Symptom",
"symptom": "Cough",
"exact": {
"quantity": 0
},
"direct_transition": "Bronchitis_Symptom2_Subsides"
},
"Bronchitis_Symptom2_Subsides": {
"type": "Symptom",
"symptom": "Mucus",
"exact": {
"quantity": 0
},
"direct_transition": "Bronchitis_Symptom4_Subsides"
},
"Bronchitis_Symptom4_Subsides": {
"type": "Symptom",
"symptom": "Sore Throat",
"exact": {
"quantity": 0
},
"direct_transition": "Bronchitis_Symptom5_Subsides"
},
"Bronchitis_Symptom5_Subsides": {
"type": "Symptom",
"symptom": "Fatigue",
"exact": {
"quantity": 0
},
"direct_transition": "Bronchitis_Symptom6_Subsides"
},
"Bronchitis_Symptom6_Subsides": {
"type": "Symptom",
"symptom": "Fever",
"exact": {
"quantity": 0
},
"direct_transition": "Bronchitis_Symptom7_Subsides"
},
"Bronchitis_Symptom7_Subsides": {
"type": "Symptom",
"symptom": "Body Aches",
"exact": {
"quantity": 0
},
"direct_transition": "Bronchitis_Symptom8_Subsides"
},
"Bronchitis_Symptom8_Subsides": {
"type": "Symptom",
"symptom": "Nasal Congestion",
"exact": {
"quantity": 0
},
"direct_transition": "Bronchitis_Symptom9_Subsides"
},
"Bronchitis_Symptom9_Subsides": {
"type": "Symptom",
"symptom": "Nausea/Vomiting",
"exact": {
"quantity": 0
},
"direct_transition": "Bronchitis_Symptom10_Subsides"
},
"Bronchitis_Symptom10_Subsides": {
"type": "Symptom",
"symptom": "Diarrhea",
"exact": {
"quantity": 0
},
"direct_transition": "Bronchitis_Symptom3_Subsides"
},
"Bronchitis_Symptom3_Subsides": {
"type": "Symptom",
"symptom": "Shortness of Breath",
"exact": {
"quantity": 0
},
"conditional_transition": [
{
"condition": {
"condition_type": "Attribute",
"attribute": "OTC_Bronchitis_Med",
"operator": "is not nil"
},
"transition": "End_OTC_Medication"
},
{
"transition": "Next_Well_Visit"
}
]
},
"End_OTC_Medication": {
"type": "MedicationEnd",
"referenced_by_attribute": "OTC_Bronchitis_Med",
"direct_transition": "Next_Well_Visit"
},
"Next_Well_Visit": {
"type": "Encounter",
"wellness": true,
"direct_transition": "End_Bronchitis_CarePlan",
"reason": "Bronchitis_Infection"
},
"End_Bronchitis_CarePlan": {
"type": "CarePlanEnd",
"referenced_by_attribute": "bronchitis_careplan",
"direct_transition": "End_Wellness_Visit"
},
"End_Wellness_Visit": {
"type": "EncounterEnd",
"direct_transition": "Potential_Infection"
}
},
"gmf_version": 1
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,491 @@
{
"name": "Chronic Ischaemic Heart Disease",
"remarks": [
"Chronic ischaemic heart disease (IHD) refers to reduced blood supply to the heart muscle due to coronary artery disease.",
"It is characterized by atherosclerotic plaque buildup in coronary arteries, leading to myocardial ischemia.",
"This module models the onset, progression, and management of chronic IHD, including stable angina and its complications.",
"Information on prevalence, progression, and treatment obtained from:",
"https://www.ncbi.nlm.nih.gov/books/NBK507846/",
"https://www.ahajournals.org/doi/10.1161/CIR.0000000000000757",
"https://www.nice.org.uk/guidance/ng185"
],
"states": {
"Initial": {
"type": "Initial",
"remarks": [
"======================================================================",
" INCIDENCE ",
"======================================================================",
"Chronic ischaemic heart disease affects approximately 3-4% of the general population.",
"It is more common in males, older adults, and those with risk factors like hypertension,",
"diabetes, hyperlipidemia, smoking, and family history of premature CAD."
],
"direct_transition": "Risk_Factor_Check"
},
"Risk_Factor_Check": {
"type": "Simple",
"complex_transition": [
{
"condition": {
"condition_type": "And",
"conditions": [
{
"condition_type": "Gender",
"gender": "M"
},
{
"condition_type": "Age",
"operator": ">=",
"quantity": 45,
"unit": "years"
}
]
},
"distributions": [
{
"distribution": 0.08,
"transition": "Delay_For_IHD_Onset"
},
{
"distribution": 0.92,
"transition": "Terminal"
}
]
},
{
"condition": {
"condition_type": "And",
"conditions": [
{
"condition_type": "Gender",
"gender": "F"
},
{
"condition_type": "Age",
"operator": ">=",
"quantity": 55,
"unit": "years"
}
]
},
"distributions": [
{
"distribution": 0.06,
"transition": "Delay_For_IHD_Onset"
},
{
"distribution": 0.94,
"transition": "Terminal"
}
]
},
{
"distributions": [
{
"distribution": 0.02,
"transition": "Delay_For_IHD_Onset"
},
{
"distribution": 0.98,
"transition": "Terminal"
}
]
}
]
},
"Delay_For_IHD_Onset": {
"type": "Delay",
"range": {
"low": 1,
"high": 10,
"unit": "years"
},
"direct_transition": "Chronic_IHD_Onset"
},
"Chronic_IHD_Onset": {
"type": "ConditionOnset",
"target_encounter": "IHD_Diagnosis_Encounter",
"assign_to_attribute": "ihd",
"codes": [
{
"system": "SNOMED-CT",
"code": "413838009",
"display": "Chronic ischemic heart disease (disorder)"
},
{
"system": "ICD-10-CM",
"code": "I25.9",
"display": "Chronic ischemic heart disease, unspecified"
}
],
"direct_transition": "Set_Angina_Status"
},
"Set_Angina_Status": {
"type": "SetAttribute",
"attribute": "angina_status",
"value": "asymptomatic",
"direct_transition": "IHD_Diagnosis_Encounter"
},
"IHD_Diagnosis_Encounter": {
"type": "Encounter",
"encounter_class": "ambulatory",
"reason": "ihd",
"codes": [
{
"system": "SNOMED-CT",
"code": "185347001",
"display": "Encounter for problem (procedure)"
}
],
"direct_transition": "Chest_Pain_Symptom"
},
"Chest_Pain_Symptom": {
"type": "Symptom",
"symptom": "chest pain",
"cause": "ihd",
"range": {
"low": 0,
"high": 30
},
"direct_transition": "Dyspnea_Symptom"
},
"Dyspnea_Symptom": {
"type": "Symptom",
"symptom": "dyspnea",
"cause": "ihd",
"range": {
"low": 0,
"high": 30
},
"direct_transition": "Fatigue_Symptom"
},
"Fatigue_Symptom": {
"type": "Symptom",
"symptom": "fatigue",
"cause": "ihd",
"range": {
"low": 0,
"high": 40
},
"direct_transition": "BP_Measurement"
},
"BP_Measurement": {
"type": "Observation",
"category": "vital-signs",
"unit": "mm[Hg]",
"codes": [
{
"system": "LOINC",
"code": "8480-6",
"display": "Systolic blood pressure"
}
],
"range": {
"low": 120,
"high": 160
},
"direct_transition": "ECG"
},
"ECG": {
"type": "Procedure",
"reason": "ihd",
"codes": [
{
"system": "SNOMED-CT",
"code": "29303009",
"display": "Electrocardiogram (procedure)"
}
],
"direct_transition": "ECG_Findings"
},
"ECG_Findings": {
"type": "Observation",
"category": "procedure",
"unit": "",
"codes": [
{
"system": "LOINC",
"code": "76547-9",
"display": "EKG impression narrative"
}
],
"value_code": {
"system": "SNOMED-CT",
"code": "164865005",
"display": "ECG: ischaemic changes (finding)"
},
"direct_transition": "Lipid_Panel"
},
"Lipid_Panel": {
"type": "Procedure",
"reason": "ihd",
"codes": [
{
"system": "SNOMED-CT",
"code": "14698002",
"display": "Lipid panel (procedure)"
}
],
"direct_transition": "LDL_Test"
},
"LDL_Test": {
"type": "Observation",
"category": "laboratory",
"unit": "mg/dL",
"codes": [
{
"system": "LOINC",
"code": "18262-6",
"display": "Cholesterol in LDL [Mass/volume] in Serum or Plasma"
}
],
"range": {
"low": 120,
"high": 190
},
"direct_transition": "HDL_Test"
},
"HDL_Test": {
"type": "Observation",
"category": "laboratory",
"unit": "mg/dL",
"codes": [
{
"system": "LOINC",
"code": "2085-9",
"display": "Cholesterol in HDL [Mass/volume] in Serum or Plasma"
}
],
"range": {
"low": 30,
"high": 50
},
"direct_transition": "Stress_Test_Decision"
},
"Stress_Test_Decision": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.8,
"transition": "Exercise_Stress_Test"
},
{
"distribution": 0.2,
"transition": "Coronary_Angiography_Decision"
}
]
},
"Exercise_Stress_Test": {
"type": "Procedure",
"reason": "ihd",
"codes": [
{
"system": "SNOMED-CT",
"code": "251269002",
"display": "Exercise stress test (procedure)"
}
],
"duration": {
"low": 30,
"high": 45,
"unit": "minutes"
},
"direct_transition": "Stress_Test_Results"
},
"Stress_Test_Results": {
"type": "Observation",
"category": "procedure",
"unit": "",
"codes": [
{
"system": "LOINC",
"code": "69066-4",
"display": "Exercise stress test Study observation"
}
],
"value_code": {
"system": "SNOMED-CT",
"code": "164873001",
"display": "Exercise ECG positive (finding)"
},
"direct_transition": "Coronary_Angiography_Decision"
},
"Coronary_Angiography_Decision": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.6,
"transition": "Coronary_Angiography"
},
{
"distribution": 0.4,
"transition": "Treatment_Plan"
}
]
},
"Coronary_Angiography": {
"type": "Procedure",
"reason": "ihd",
"codes": [
{
"system": "SNOMED-CT",
"code": "33367005",
"display": "Coronary arteriography (procedure)"
}
],
"duration": {
"low": 45,
"high": 90,
"unit": "minutes"
},
"direct_transition": "Angiography_Results"
},
"Angiography_Results": {
"type": "Observation",
"category": "procedure",
"unit": "",
"codes": [
{
"system": "LOINC",
"code": "79378-6",
"display": "Coronary angiography Narrative"
}
],
"value_code": {
"system": "SNOMED-CT",
"code": "233817007",
"display": "Coronary artery stenosis (disorder)"
},
"direct_transition": "Update_IHD_Condition"
},
"Update_IHD_Condition": {
"type": "ConditionEnd",
"condition_onset": "ihd",
"direct_transition": "Specific_IHD_Diagnosis"
},
"Specific_IHD_Diagnosis": {
"type": "ConditionOnset",
"target_encounter": "IHD_Diagnosis_Encounter",
"assign_to_attribute": "ihd",
"codes": [
{
"system": "SNOMED-CT",
"code": "413838009",
"display": "Chronic ischemic heart disease (disorder)"
},
{
"system": "ICD-10-CM",
"code": "I25.1",
"display": "Atherosclerotic heart disease of native coronary artery"
}
],
"direct_transition": "Treatment_Plan"
},
"Treatment_Plan": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.9,
"transition": "Medical_Management"
},
{
"distribution": 0.1,
"transition": "Revascularization_Decision"
}
]
},
"Medical_Management": {
"type": "Simple",
"direct_transition": "Aspirin_Therapy"
},
"Aspirin_Therapy": {
"type": "MedicationOrder",
"assign_to_attribute": "aspirin",
"reason": "ihd",
"codes": [
{
"system": "RxNorm",
"code": "1191",
"display": "Aspirin 81 MG Oral Tablet"
}
],
"direct_transition": "Statin_Therapy"
},
"Statin_Therapy": {
"type": "MedicationOrder",
"assign_to_attribute": "statin",
"reason": "ihd",
"codes": [
{
"system": "RxNorm",
"code": "617311",
"display": "Atorvastatin 20 MG Oral Tablet"
}
],
"direct_transition": "Beta_Blocker_Decision"
},
"Beta_Blocker_Decision": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.7,
"transition": "Beta_Blocker_Therapy"
},
{
"distribution": 0.3,
"transition": "ACE_Inhibitor_Decision"
}
]
},
"Beta_Blocker_Therapy": {
"type": "MedicationOrder",
"assign_to_attribute": "beta_blocker",
"reason": "ihd",
"codes": [
{
"system": "RxNorm",
"code": "866924",
"display": "Metoprolol Tartrate 25 MG Oral Tablet"
}
],
"direct_transition": "ACE_Inhibitor_Decision"
},
"ACE_Inhibitor_Decision": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.6,
"transition": "ACE_Inhibitor_Therapy"
},
{
"distribution": 0.4,
"transition": "Nitrate_Decision"
}
]
},
"ACE_Inhibitor_Therapy": {
"type": "MedicationOrder",
"assign_to_attribute": "ace_inhibitor",
"reason": "ihd",
"codes": [
{
"system": "RxNorm",
"code": "1299896",
"display": "Lisinopril 10 MG Oral Tablet"
}
],
"direct_transition": "Nitrate_Decision"
},
"Nitrate_Decision": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.5,
"transition": "Nitrate_Therapy"
},
{
"distribution": 0.5,
"transition": "IHD_CarePlan"
}
]
}}}

View File

@@ -0,0 +1,464 @@
{
"name": "Chronic Kidney Disease",
"remarks": [],
"states": {
"Initial": {
"type": "Initial",
"direct_transition": "Initial_Kidney_Health"
},
"Initial_Kidney_Health": {
"type": "SetAttribute",
"attribute": "ckd",
"value": 0,
"distributed_transition": [
{
"transition": "Guard_for_Htn_or_DM",
"distribution": 0.998
},
{
"transition": "Nephropathy_Progression",
"distribution": 0.001
},
{
"transition": "Renal Dysplasia",
"distribution": 0.001
}
]
},
"Guard_for_Htn_or_DM": {
"type": "Guard",
"allow": {
"condition_type": "Or",
"conditions": [
{
"condition_type": "Attribute",
"attribute": "hypertension",
"operator": "is not nil"
},
{
"condition_type": "Attribute",
"attribute": "diabetes",
"operator": "is not nil"
}
]
},
"direct_transition": "Nephropathy_Progression"
},
"Nephropathy_Progression": {
"type": "Delay",
"exact": {
"quantity": 1,
"unit": "months"
},
"remarks": [
"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4727808/",
"There are 5 defined stages of kidney disease; stage 5 is End-stage where dialysis is necessary",
"Prevalence of Nephropathy is 34.5% - http://link.springer.com/chapter/10.1007%2F978-1-4939-0793-9_2",
"Prevalence of microalbuminuria is ~ 28.8% - https://www.ncbi.nlm.nih.gov/pubmed/11877563",
"Prevalence of End stage renal disease is ~ .78% - ",
"https://www.cdc.gov/diabetes/pdfs/data/2014-report-estimates-of-diabetes-and-its-burden-in-the-united-states.pdf"
],
"complex_transition": [
{
"condition": {
"condition_type": "And",
"conditions": [
{
"condition_type": "Attribute",
"attribute": "veteran",
"operator": "is not nil"
},
{
"condition_type": "Attribute",
"attribute": "ckd",
"operator": "==",
"value": 0
}
]
},
"distributions": [
{
"distribution": 0.99,
"transition": "Nephropathy_Progression"
},
{
"distribution": 0.01,
"transition": "Set_CKD_1 Damage"
}
]
},
{
"condition": {
"condition_type": "Attribute",
"attribute": "ckd",
"operator": "==",
"value": 0
},
"distributions": [
{
"distribution": 0.9982,
"transition": "Nephropathy_Progression"
},
{
"distribution": 0.0018,
"transition": "Set_CKD_1 Damage"
}
]
},
{
"condition": {
"condition_type": "Attribute",
"attribute": "ckd",
"operator": "==",
"value": 1
},
"distributions": [
{
"distribution": 0.98,
"transition": "Set_CKD_1 Damage"
},
{
"distribution": 0.02,
"transition": "Set_CKD_2 Damage"
}
]
},
{
"condition": {
"condition_type": "Attribute",
"attribute": "ckd",
"operator": "==",
"value": 2
},
"distributions": [
{
"distribution": 0.99,
"transition": "Set_CKD_2 Damage"
},
{
"distribution": 0.01,
"transition": "Set_CKD_3 Damage"
}
]
},
{
"condition": {
"condition_type": "Attribute",
"attribute": "ckd",
"operator": "==",
"value": 3
},
"distributions": [
{
"distribution": 0.99,
"transition": "Set_CKD_3 Damage"
},
{
"distribution": 0.01,
"transition": "Set_CKD_4 Damage"
}
]
},
{
"condition": {
"condition_type": "Attribute",
"attribute": "ckd",
"operator": "==",
"value": 4
},
"distributions": [
{
"distribution": 0.99,
"transition": "Set_CKD_4 Damage"
},
{
"distribution": 0.01,
"transition": "Expected_Lifespan_for_ESRD"
}
]
},
{
"condition": {
"condition_type": "Attribute",
"attribute": "ckd",
"operator": "==",
"value": 5
},
"transition": "Expected_Lifespan_for_ESRD"
}
]
},
"Set_Nephropathy": {
"type": "SetAttribute",
"attribute": "nephropathy",
"value": true,
"direct_transition": "CKD1_Symptom_1"
},
"Set_Microalbuminuria": {
"type": "SetAttribute",
"attribute": "microalbuminuria",
"value": true,
"direct_transition": "CKD2_Symptom_1"
},
"Set_Proteinuria": {
"type": "SetAttribute",
"attribute": "proteinuria",
"value": true,
"direct_transition": "CKD3_Symptom_1"
},
"Expected_Lifespan_for_ESRD": {
"type": "Death",
"range": {
"low": 4,
"high": 10,
"unit": "years"
},
"codes": [
{
"system": "SNOMED-CT",
"code": "46177005",
"display": "End-stage renal disease (disorder)"
}
],
"remarks": [
"Life expectency depends on many factors, but for patients > 40 it's generally less than 10 years with dialysis",
"http://link.springer.com/article/10.1007/s00467-016-3383-8 (Table 2"
],
"direct_transition": "Set_CKD_5 Damage"
},
"Loop_back_to_Start": {
"type": "Simple",
"direct_transition": "Nephropathy_Progression"
},
"Set_CKD_1 Damage": {
"type": "SetAttribute",
"attribute": "ckd",
"direct_transition": "Set_Nephropathy",
"value": 1
},
"Set_CKD_2 Damage": {
"type": "SetAttribute",
"attribute": "ckd",
"direct_transition": "Set_Microalbuminuria",
"value": 2
},
"Set_CKD_3 Damage": {
"type": "SetAttribute",
"attribute": "ckd",
"value": 3,
"direct_transition": "Set_Proteinuria"
},
"Set_CKD_4 Damage": {
"type": "SetAttribute",
"attribute": "ckd",
"value": 4,
"direct_transition": "CKD4_Symptom_1"
},
"Set_CKD_5 Damage": {
"type": "SetAttribute",
"attribute": "ckd",
"direct_transition": "CKD5_Symptom_1",
"value": 5
},
"CKD1_Symptom_1": {
"type": "Symptom",
"symptom": "Hunger",
"range": {
"low": 1,
"high": 100
},
"direct_transition": "CKD1_Symptom_2"
},
"CKD2_Symptom_1": {
"type": "Symptom",
"symptom": "Hunger",
"range": {
"low": 20,
"high": 100
},
"direct_transition": "CKD2_Symptom_2"
},
"CKD2_Symptom_2": {
"type": "Symptom",
"symptom": "Fatigue",
"range": {
"low": 20,
"high": 100
},
"direct_transition": "CKD2_Symptom_3"
},
"CKD2_Symptom_3": {
"type": "Symptom",
"symptom": "Frequent Urination",
"range": {
"low": 20,
"high": 100
},
"direct_transition": "CKD2_Symptom_4"
},
"CKD2_Symptom_4": {
"type": "Symptom",
"symptom": "Thirst",
"range": {
"low": 20,
"high": 100
},
"direct_transition": "Loop_back_to_Start"
},
"CKD1_Symptom_2": {
"type": "Symptom",
"symptom": "Fatigue",
"range": {
"low": 1,
"high": 100
},
"direct_transition": "CKD1_Symptom_3"
},
"CKD1_Symptom_3": {
"type": "Symptom",
"symptom": "Frequent Urination",
"range": {
"low": 1,
"high": 100
},
"direct_transition": "CKD1_Symptom_4"
},
"CKD1_Symptom_4": {
"type": "Symptom",
"symptom": "Thirst",
"range": {
"low": 1,
"high": 100
},
"direct_transition": "Loop_back_to_Start"
},
"CKD3_Symptom_1": {
"type": "Symptom",
"symptom": "Hunger",
"range": {
"low": 40,
"high": 100
},
"direct_transition": "CKD3_Symptom_2"
},
"CKD3_Symptom_2": {
"type": "Symptom",
"symptom": "Fatigue",
"range": {
"low": 40,
"high": 100
},
"direct_transition": "CKD3_Symptom_3"
},
"CKD3_Symptom_3": {
"type": "Symptom",
"symptom": "Frequent Urination",
"range": {
"low": 40,
"high": 100
},
"direct_transition": "CKD3_Symptom_4"
},
"CKD3_Symptom_4": {
"type": "Symptom",
"symptom": "Thirst",
"range": {
"low": 40,
"high": 100
},
"direct_transition": "Loop_back_to_Start"
},
"CKD5_Symptom_1": {
"type": "Symptom",
"symptom": "Hunger",
"range": {
"low": 50,
"high": 100
},
"remarks": [
"Without intervention, 20-40 percent of patients with type 2 diabetes/microalbuminuria, will evolve to macroalbuminuria.",
"Shlipak, Michael. 'Clinical Evidence Handbook: Diabetic Nephropathy: Preventing Progression - American Family Physician'. www.aafp.org."
],
"direct_transition": "CKD5_Symptom_2"
},
"CKD5_Symptom_2": {
"type": "Symptom",
"symptom": "Fatigue",
"range": {
"low": 50,
"high": 100
},
"direct_transition": "CKD5_Symptom_3"
},
"CKD5_Symptom_3": {
"type": "Symptom",
"symptom": "Frequent Urination",
"range": {
"low": 50,
"high": 100
},
"direct_transition": "CKD5_Symptom_4"
},
"CKD5_Symptom_4": {
"type": "Symptom",
"symptom": "Thirst",
"range": {
"low": 50,
"high": 100
},
"direct_transition": "Loop_back_to_Start"
},
"CKD4_Symptom_1": {
"type": "Symptom",
"symptom": "Hunger",
"cause": "",
"direct_transition": "CKD4_Symptom_2",
"range": {
"low": 45,
"high": 2
}
},
"CKD4_Symptom_2": {
"type": "Symptom",
"symptom": "Fatigue",
"cause": "",
"direct_transition": "CKD4_Symptom_3",
"range": {
"low": 45,
"high": 100
}
},
"CKD4_Symptom_3": {
"type": "Symptom",
"symptom": "Frequent Urination",
"cause": "",
"direct_transition": "CKD4_Symptom_4",
"range": {
"low": 45,
"high": 100
}
},
"CKD4_Symptom_4": {
"type": "Symptom",
"symptom": "Thirst",
"cause": "",
"direct_transition": "Loop_back_to_Start",
"range": {
"low": 45,
"high": 100
}
},
"Renal Dysplasia": {
"type": "ConditionOnset",
"codes": [
{
"system": "SNOMED-CT",
"code": "204949001",
"display": "Renal dysplasia (disorder)"
}
],
"direct_transition": "Expected_Lifespan_for_ESRD"
}
},
"gmf_version": 1
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,401 @@
{
"name": "Common Cold",
"remarks": [
"This module simulates the progression of the common cold (acute nasopharyngitis).",
"The common cold is a viral infectious disease of the upper respiratory tract that primarily affects the nose.",
"Symptoms include coughing, sore throat, runny nose, sneezing, headache, and fever.",
"Most people recover within 7-10 days, though some symptoms can last up to three weeks.",
"This module includes risk factors, diagnosis, treatment, and potential complications.",
"ICD-10 code: J00",
"Category: Respiratory"
],
"states": {
"Initial": {
"type": "Initial",
"direct_transition": "Age_Guard"
},
"Age_Guard": {
"type": "Guard",
"allow": {
"condition_type": "Age",
"operator": ">=",
"quantity": 0,
"unit": "years"
},
"distributed_transition": [
{
"distribution": 0.95,
"transition": "Potential_Cold_Onset"
},
{
"distribution": 0.05,
"transition": "Terminal"
}
]
},
"Potential_Cold_Onset": {
"type": "Delay",
"remarks": [
"Common colds are more frequent in fall and winter seasons"
],
"range": {
"low": 3,
"high": 12,
"unit": "months"
},
"distributed_transition": [
{
"distribution": 0.7,
"transition": "Cold_Onset"
},
{
"distribution": 0.3,
"transition": "Potential_Cold_Onset"
}
]
},
"Cold_Onset": {
"type": "ConditionOnset",
"target_encounter": "Cold_Encounter",
"codes": [
{
"system": "SNOMED-CT",
"code": "82272006",
"display": "Common cold (disorder)"
}
],
"direct_transition": "Cold_Symptoms"
},
"Cold_Symptoms": {
"type": "Symptom",
"symptom": "Nasal Congestion",
"range": {
"low": 50,
"high": 100
},
"direct_transition": "Sore_Throat_Symptom"
},
"Sore_Throat_Symptom": {
"type": "Symptom",
"symptom": "Sore Throat",
"range": {
"low": 30,
"high": 70
},
"direct_transition": "Cough_Symptom"
},
"Cough_Symptom": {
"type": "Symptom",
"symptom": "Cough",
"range": {
"low": 40,
"high": 90
},
"direct_transition": "Headache_Symptom"
},
"Headache_Symptom": {
"type": "Symptom",
"symptom": "Headache",
"range": {
"low": 20,
"high": 60
},
"direct_transition": "Fever_Symptom"
},
"Fever_Symptom": {
"type": "Symptom",
"symptom": "Fever",
"range": {
"low": 0,
"high": 40
},
"direct_transition": "Fatigue_Symptom"
},
"Fatigue_Symptom": {
"type": "Symptom",
"symptom": "Fatigue",
"range": {
"low": 30,
"high": 70
},
"direct_transition": "Decide_To_Visit_Doctor"
},
"Decide_To_Visit_Doctor": {
"type": "Delay",
"range": {
"low": 1,
"high": 3,
"unit": "days"
},
"distributed_transition": [
{
"distribution": 0.3,
"transition": "Cold_Encounter"
},
{
"distribution": 0.7,
"transition": "Self_Care"
}
]
},
"Self_Care": {
"type": "Delay",
"range": {
"low": 5,
"high": 10,
"unit": "days"
},
"direct_transition": "Cold_Recovery"
},
"Cold_Encounter": {
"type": "Encounter",
"encounter_class": "ambulatory",
"reason": "Cold_Onset",
"codes": [
{
"system": "SNOMED-CT",
"code": "185345009",
"display": "Encounter for symptom"
}
],
"direct_transition": "Cold_Diagnosis"
},
"Cold_Diagnosis": {
"type": "Procedure",
"target_encounter": "Cold_Encounter",
"reason": "Cold_Onset",
"codes": [
{
"system": "SNOMED-CT",
"code": "162673000",
"display": "General examination of patient (procedure)"
}
],
"direct_transition": "Record_Cold_Diagnosis"
},
"Record_Cold_Diagnosis": {
"type": "DiagnosticReport",
"number_of_observations": 0,
"codes": [
{
"system": "SNOMED-CT",
"code": "162673000",
"display": "General examination of patient (procedure)"
}
],
"direct_transition": "Prescribe_Treatment"
},
"Prescribe_Treatment": {
"type": "Simple",
"distributed_transition": [
{
"distribution": 0.5,
"transition": "Prescribe_Acetaminophen"
},
{
"distribution": 0.3,
"transition": "Prescribe_Ibuprofen"
},
{
"distribution": 0.2,
"transition": "Prescribe_Decongestant"
}
]
},
"Prescribe_Acetaminophen": {
"type": "MedicationOrder",
"target_encounter": "Cold_Encounter",
"reason": "Cold_Onset",
"codes": [
{
"system": "RxNorm",
"code": "313782",
"display": "Acetaminophen 325 MG Oral Tablet"
}
],
"direct_transition": "Cold_Encounter_End"
},
"Prescribe_Ibuprofen": {
"type": "MedicationOrder",
"target_encounter": "Cold_Encounter",
"reason": "Cold_Onset",
"codes": [
{
"system": "RxNorm",
"code": "197806",
"display": "Ibuprofen 200 MG Oral Tablet"
}
],
"direct_transition": "Cold_Encounter_End"
},
"Prescribe_Decongestant": {
"type": "MedicationOrder",
"target_encounter": "Cold_Encounter",
"reason": "Cold_Onset",
"codes": [
{
"system": "RxNorm",
"code": "1020137",
"display": "Pseudoephedrine Hydrochloride 30 MG Oral Tablet"
}
],
"direct_transition": "Cold_Encounter_End"
},
"Cold_Encounter_End": {
"type": "EncounterEnd",
"direct_transition": "Check_For_Complications"
},
"Check_For_Complications": {
"type": "Delay",
"range": {
"low": 3,
"high": 7,
"unit": "days"
},
"distributed_transition": [
{
"distribution": 0.05,
"transition": "Develop_Sinusitis"
},
{
"distribution": 0.03,
"transition": "Develop_Ear_Infection"
},
{
"distribution": 0.92,
"transition": "Cold_Recovery"
}
]
},
"Develop_Sinusitis": {
"type": "ConditionOnset",
"target_encounter": "Complication_Encounter",
"codes": [
{
"system": "SNOMED-CT",
"code": "36971009",
"display": "Sinusitis (disorder)"
}
],
"direct_transition": "Complication_Encounter"
},
"Develop_Ear_Infection": {
"type": "ConditionOnset",
"target_encounter": "Complication_Encounter",
"codes": [
{
"system": "SNOMED-CT",
"code": "65363002",
"display": "Otitis media (disorder)"
}
],
"direct_transition": "Complication_Encounter"
},
"Complication_Encounter": {
"type": "Encounter",
"encounter_class": "ambulatory",
"codes": [
{
"system": "SNOMED-CT",
"code": "185345009",
"display": "Encounter for symptom"
}
],
"direct_transition": "Treat_Complication"
},
"Treat_Complication": {
"type": "MedicationOrder",
"target_encounter": "Complication_Encounter",
"codes": [
{
"system": "RxNorm",
"code": "1658139",
"display": "Amoxicillin 500 MG Oral Tablet"
}
],
"direct_transition": "Complication_Encounter_End"
},
"Complication_Encounter_End": {
"type": "EncounterEnd",
"direct_transition": "Complication_Recovery"
},
"Complication_Recovery": {
"type": "Delay",
"range": {
"low": 7,
"high": 14,
"unit": "days"
},
"direct_transition": "End_Complication"
},
"End_Complication": {
"type": "ConditionEnd",
"direct_transition": "Cold_Recovery"
},
"Cold_Recovery": {
"type": "Delay",
"range": {
"low": 1,
"high": 3,
"unit": "days"
},
"direct_transition": "End_Cold_Symptoms"
},
"End_Cold_Symptoms": {
"type": "Symptom",
"symptom": "Nasal Congestion",
"exact": {
"quantity": 0
},
"direct_transition": "End_Sore_Throat"
},
"End_Sore_Throat": {
"type": "Symptom",
"symptom": "Sore Throat",
"exact": {
"quantity": 0
},
"direct_transition": "End_Cough"
},
"End_Cough": {
"type": "Symptom",
"symptom": "Cough",
"exact": {
"quantity": 0
},
"direct_transition": "End_Headache"
},
"End_Headache": {
"type": "Symptom",
"symptom": "Headache",
"exact": {
"quantity": 0
},
"direct_transition": "End_Fever"
},
"End_Fever": {
"type": "Symptom",
"symptom": "Fever",
"exact": {
"quantity": 0
},
"direct_transition": "End_Fatigue"
},
"End_Fatigue": {
"type": "Symptom",
"symptom": "Fatigue",
"exact": {
"quantity": 0
},
"direct_transition": "End_Cold"
},
"End_Cold": {
"type": "ConditionEnd",
"condition_onset": "Cold_Onset",
"direct_transition": "Potential_Cold_Onset"
},
"Terminal": {
"type": "Terminal"
}
}
}

Some files were not shown because too many files have changed in this diff Show More