Health-GPS

Logo

Global Health Policy Simulation model

View the Project on GitHub imperialCHEPI/healthgps

Global Health Policy Simulation model

Home Quick Start User Guide Schemas Models Architecture Data Model Developer Guide Technical docs API

Software Architecture

Source layout: src/HealthGPS (engine), src/HealthGPS.Core (Data API / POCOs), src/HealthGPS.Input (file datastore + config), src/HealthGPS.Console (host), src/HealthGPS.Tests. ADEVS is vendored under src/external/adevs.

The Health-GPS software architecture uses a modular design. It is written in modern C++20. The deployable stack has four main pieces:

Health-GPS Components
Health-GPS Microsimulation Components

These components along with the physical data storage are the minimum package to deploy and use the Health-GPS microsimulation. All input data processing, model parameters fitting, and results analysis procedures are carried out outside the microsimulation using tools such R, Julia and Python which are very efficient in data wrangling, statistical analysis, and machine learning algorithms.

The Health-GPS framework adopts a modular design to specify the building blocks necessary to compose the overall system, several modules and sub-model types are required as shown below.

Health-GPS Modules
High-level Architecture of the Health-GPS Framework

The simulation engine clock and events scheduling is based on the Discrete Event System Specification (DEVS) and provided by the ADEVS library. The simulation results are streamed asynchronous to the outside world via the message bus instance provided to the model by the host application during initialisation.

The software architecture defines interfaces for modules, sub-models, and external communication; these abstractions provide decoupling, reuse, and flexibility for composing the microsimulation to answer different research questions. All modules share a common interface, as shown below, to enable dynamic registration of different modules version using a factory pattern, which also makes available the underline data infrastructure and user inputs for module instance creation.

Health-GPS Common Module Interface
Simulation Module Common Interface

The simulation module type enumeration (SimulationModuleType in src/HealthGPS/interfaces.h) is: RiskFactor, SES, Demographic, Disease, Analysis. The engine asks the module factory for each type. RuntimeContext holds the virtual population, scenario, run number, time, RNG, bus, and settings for module calls.

Health-GPS Module Factory
Module Factory Class Diagram with Concrete Builder Function example

The module builder functions have access to both the model inputs and backend data storage (Repository) when requested to create the respective simulation module instance. The Repository interface shown below provides read-only access to external datasets loaded via configuration to parameterise the risk factor module, and exposes the Datastore interface implementation. The factory registered module builders can retrieve the required raw data, reshape, and combine to create the respective module parameters definition and instance.

Health-GPS Repository
Data Repository Interface Diagram

This design exposes datasets to factory builders. In the current Console host, a CachedRepository wraps the datastore and registered risk-factor model definitions so baseline and intervention simulations can share loaded data.

The backend data storage interface shown below defines the Datastore contract: a typed, storage-agnostic access layer.

Health-GPS Data API
Backend Data API Interface

See Data Model for the backend data model.

To take the virtual population through time, the simulation modules have different requirements, and consequently the simulation module interface has been extended with new properties and operations to satisfy the different modules as shown below.

Health-GPS Extended Module Interface
Extended Simulation Module Common Interface

All modules must initialise the virtual population at the beginning of the simulation and update the respective properties at each subsequent simulated time step until the simulation ends. Modules providing additional functionality to the simulation algorithm such as population trends and disease indicators have specific extension added to their interfaces.

The two host modules, risk factor and disease respectively, are special containers for similar sub-models and likewise are responsible for managing the creation, ownership and execution order when requested by the simulation engine or other modules.

The risk factor module hosts models supplied through configuration. Models implement RiskFactorModel with type Static or Dynamic (src/HealthGPS/risk_factor_model.h). Concrete types include hierarchical linear models, static linear models (FINCH-style), and Kevin Hall. Static models initialise the population; dynamic models update it each year.

Health-GPS Hierarchical Models
Hierarchical Linear Model Common Interface

The disease module hosts multiple instances of disease models from known groups, configured for different diseases definition. The disease model public interface is shown below; diseases are uniquely identified by type, two groups of diseases a current modelled: others and cancers, the first represents general noncommunicable diseases, and the second types of cancer respectively.

Health-GPS Disease Models
Disease Model Common Interface

The main difference between the two groups of diseases is on internal modelling, both groups’ definition is country-based and include rates for disease: prevalence, incidence, mortality and remission by age and gender; and relative risks for diseases and risk factors. However, cancers detection, mortality and remission are modelled differently from the others’ group and require an additional set of parameters data to be provided as part of the definition.

Virtual Population

All modules act on a virtual population of entities, individuals, or actors, that are the centre of the microsimulation model. The Health-GPS population is dynamic and changes over time with births, deaths and immigration being the events affecting the population size. The entire population is stored using a C++ standard library vector<T> for dynamic memory management and exception safety, the vector is protected with the thin wrapper for easy access.

Below are the class diagrams for the thin Population wrapper, the virtual Person data structure and associated types as used to represent individuals within the simulated virtual population.

Health-GPS Virtual Population
Virtual Population’s Entity definition

Individuals get a lifetime-unique id within one Population (not reused after death or emigration; default-constructed persons stay unassigned until placed). Main fields on Person (src/HealthGPS/person.h):

Helpers such as is_active(), get_risk_factor_value(), and gender/sector/income converters live on Person.

Simulation Engine

The simulation engine manages the clock, DEVS scheduling, and module call order. Health-GPS uses a slim ADEVS-based model (adevs::Model<int>), vendored under src/external/adevs.

The concrete engine is class hgps::Simulation (src/HealthGPS/simulation.h). There is no separate HealthGPS engine class and no SimulationDefinition type in the current tree.

Construction (as used by the Console host):

Simulation(SimulationModuleFactory& factory,
           shared_ptr<const EventAggregator> bus,
           shared_ptr<const ModelInput> inputs,
           unique_ptr<Scenario> scenario)

During construction the engine asks the factory for each SimulationModuleType, owns those modules, and builds a RuntimeContext (population, scenario, settings, RNG, bus). Randomness goes through the RNG held on the context (seeded per run via setup_run).

Health-GPS Engine
Health-GPS Simulation Engine

Outside communication uses EventAggregator / subscribers. Message kinds include errors, info, runner progress, analysis results, and optional individual-tracking events.

Health-GPS Engine
Health-GPS Message Bus Interface

The host supplies the bus when constructing Simulation. Analysis publishes result messages; Console writers subscribe and write files.

The engine workflow covers lifecycle, scenario evaluation, and a single run. The Runner executive decides how many replications to execute and whether baseline alone or baseline+intervention pairs run.

Health-GPS Engine Workflow
Health-GPS Simulation Engine Workflow

Call order is fixed in Simulation::initialise_population / update_population (src/HealthGPS/simulation.cpp).

Initialise Population

Health-GPS Initialise Population
Initialise Population Algorithm (Sequence Diagram #1)

Order: Demographic -> SES -> RiskFactor -> Disease -> Analysis.

Update Population

Health-GPS Update Population
Update Population Algorithm (Sequence Diagram #2)

Order: Demographic (with disease for mortality) -> net immigration -> SES -> RiskFactor -> Disease -> Analysis.

Empty squares on the scenario timeline mark synchronisation between baseline and intervention (see Policy Scenarios).

Policy Scenarios

Each Simulation takes one Scenario. Two kinds are used: Baseline (status-quo trends) and Intervention (policy that changes risk-factor paths for a target window). Scenario is not a SimulationModuleType.

Health-GPS Policy Scenarios Interface
Policy Scenario Common Interface

Baseline usually passes risk-factor values through unchanged. Intervention scenarios apply policy rules (and often external data) when invoked.

Baseline and intervention runs can be paired with shared-memory synchronisation (SyncChannel) so the intervention side waits for baseline messages at agreed points.

Health-GPS Policy Scenarios Sync
Policy Scenario’s Data Synchronisation Mechanism

Scaling across machines with a broker (RabbitMQ, Kafka, and so on) is a possible future host design; the current Console path uses in-process pairing.

Simulation Executive

The simulation executive creates the simulation running environment, instructs the simulation engine to evaluate the experiment scenarios for a pre-defined number of runs, manage master seeds generation, notify progress, and handle experiment for cancellation. The Runner class shown below, implements the Health-GPS simulation executive.

Health-GPS Runner Class Diagram
Simulation Executive Class Diagram

Two modes of evaluating a simulation experiment as provided by the simulation executive, using the run function with overloaded parameters. The two paths of execution are illustration below, the first simulates no-intervention, baseline scenario only experiments, while the second simulates intervention experiments with baseline and intervention scenarios evaluated as a pair, and data synchronisation as described above.

Health-GPS Simulation Runner
Health-GPS Simulation Executive Activity Diagram

Experiment scenarios are evaluated in parallel using multiple threads, however the need to exchange data between scenarios creates an indirect synchronisation with a small overhead. The ADEVS executive, Simulator class, is use inside each thread loop to execute the respective experiment scenario. The simulation executive communicates with the outside world via messages, ideally sharing the same message bus instance with the simulation engine, indicating the start and finish of the experiment, notifying error and cancellation.

The message bus mechanism decouples the sender from the receiver, typically one or more event monitors are used to subscriber for messages, receive, queue, and process the messages queue on its own pace and thread, common activities are display on screen, stream over the internet, summarise results and/or log to file.

Deployment

The various components of the Health-GPS ecosystem can be deployed to multiple computing platforms. The four components are packaged together into the host application executable, which is purpose built for each target platforms as shown below. The backend data storage is platform independent, but must be available, accessible, and properly configured for the application to work correctly at runtime.

Health-GPS Deployment
Health-GPS Deployment Package

The version of the libraries required by the application at runtime depends on the compiler being used to build Health-GPS executable. The source code is portable for compilers supporting C++20 standard, however the resulting binaries are platform dependent and must be built, tested, and deployed accordingly for the model to work as expected.

See Data Model and Developer Guide for detailed information on the backend data storage and the various interfaces implementation respectively.


Topic Document
Developer docs index developer/README.md
Data model Data Model
Build guide Developer Guide
GitHub flow GitHub Flow
FINCH / income / predictors FINCH guide
Feb 2026 integrated changes Update report
Windows MSVC builds MSVC troubleshooting
Technical docs Technical documentation index
Documentation home documentation/README.md


Author: Mahima Ghosh