-
Notifications
You must be signed in to change notification settings - Fork 791
Generic Module Framework: Submodules
The Generic Module Framework supports the concept of "submodules". A submodule is a reusable series of states that can be used at any time by any other generic module. In general, submodules are used to define a series of states that are either:
- Used repeatedly in the same module, or
- Used repeatedly by several different modules
For example, in Synthea submodules are used to:
-
Perform several Observations and Procedures that constitute a pregnancy workup. These states are reused at every pregnant patient's visit to the doctor, more than 10 times within the
pregnancymodule. -
Prescribe a common medication, such as an over-the-counter pain reliever, or antihistamine. The
medications/otc_pain_relieversubmodule is used by several main modules in Synthea where a pain reliever is needed.
Submodules may themselves call submodules, although this is uncommon.
All modules and submodules are kept in the src/main/resources/modules/ directory. For example, consider the following hierarchy:
modules/
asthma.json
diabetes.json
medications/
otc_pain_reliever.json
otc_antihistamine.json
pregnancy.json
All modules at the top-level of the modules/ directory are considered "main modules". When generating a new patient record, Synthea starts with all main modules only. Depending on the progression of the main modules, submodules may then be called. In the example above, asthma, diabetes, and pregnancy are main modules.
Any modules in folders within the modules/ directory are considered "submodules". Synthea will not use these modules to generate a new patient record unless they are explicity called by a main module using a CallSubmodule state. In the example above, medications/otc_pain_reliever and medications/otc_antihistamine are submodules.
Each main module runs in a "context" that keeps track of states available to the module, a history of states that have been processed, and the current_state that is being processed in a given time step. When a CallSubmodule state is processed Synthea does the following:
- Saves the
keythat refers to the current module being processed so it can be retrieved and resumed later. - Saves the
current_stateof the current module being processed. In practice this is always theCallSubmodulestate so its transition may be used when the submodule eventually returns. - Loads the submodule from the global set of modules and resumes processing states in the same time step, starting with the submodule's
Initialstate.
A submodule "returns" when its Terminal state is reached. At that time, Synthea does the following:
- Returns to the calling module
- Resumes processing states in the same time step starting with the next state that the
CallSubmodulestate transitions to.
Consider a submodule with one MedicationOrder state that prescribes a medication. When processed, it's history may look like:
/===============================================================================
| Medication Submodule Log
|===============================================================================
| Entered | Exited | State
|---------------------------|---------------------------|-----------------------
| 2017-01-17T09:50:41-05:00 | 2017-01-17T09:50:41-05:00 | Initial
| 2017-01-17T09:50:41-05:00 | 2017-01-17T09:50:41-05:00 | Prescribe_Medication
| 2017-01-17T09:50:41-05:00 | 2017-01-17T09:50:41-05:00 | Med_Terminal
\===============================================================================
When that submodule is called by a main module, their collective history may look like:
/===============================================================================
| Main Module Log
|===============================================================================
| Entered | Exited | State
|---------------------------|---------------------------|-----------------------
| 2017-01-17T09:50:41-05:00 | 2017-01-17T09:50:41-05:00 | Initial
| 2017-01-17T09:50:41-05:00 | 2017-01-17T09:50:41-05:00 | Example_Condition
| 2017-01-17T09:50:41-05:00 | 2017-01-17T09:50:41-05:00 | Encounter
| 2017-01-17T09:50:41-05:00 | 2017-01-17T09:50:41-05:00 | CallSubmodule
| 2017-01-17T09:50:41-05:00 | 2017-01-17T09:50:41-05:00 | Initial
| 2017-01-17T09:50:41-05:00 | 2017-01-17T09:50:41-05:00 | Prescribe_Medication
| 2017-01-17T09:50:41-05:00 | 2017-01-17T09:50:41-05:00 | Med_Terminal
| 2017-01-17T09:50:41-05:00 | | Terminal
\===============================================================================
As you can see, the submodule's states are processed inline with the main module's states when called. To those familiar with programming, calling a submodule may seem analogous to executing a function.