A composable ecosystem for infectious disease modelling
Infectious disease models turn data into evidence for decisions, in routine surveillance and during outbreaks. For that evidence to be useful it has to be timely, rigorous, and collaborative. Today’s approaches struggle to be all three at once, and closing that gap is what EpiAware is for.
This starts with the workflow
Building a model that can be trusted is a process, not a single step. You write down what you think is going on, simulate from it, fit it to data, criticise the result, change your mind, and go round again. We set that out in a workflow for infectious disease modelling, which adapts the Bayesian workflow to the awkward realities of this field, where the question shifts under you, the data are poorly characterised, and the surveillance system changes while you are using it.
One of the stages in that workflow is modularisation, breaking a model into parts that can be reasoned about separately. That is easy to prescribe and hard to do, because the software usually will not let you. EpiAware is our attempt to build software where the workflow is actually followable.
Chained models and joint models
Say you want to know how fast something is spreading. One way is to chain models together. One team turns swab results into a prevalence estimate and hands you a number with an error bar. You turn that into an incidence estimate, and someone else turns that into a growth rate. This is flexible, and it lets different people own different links, which is why it is so common. It is also lossy. Every handover throws information away and quietly inherits the assumptions of the step before it, and the uncertainty that arrives at the end is not the uncertainty you started with.
The alternative is a joint model. That simply means writing down one description of everything at once, how infections spread, how they show up in swabs, how those swabs get sampled and reported, then fitting that whole description to the raw data in a single step. Nothing gets frozen into a point estimate along the way. Uncertainty flows from end to end, and if the swab model is wrong, the transmission estimates know about it.
The catch is that joint models have had to be built from scratch, by one team, every time. They are hard to write, they need expertise across several domains at once, and what you end up with is a monolith that solves one problem and cannot be taken apart.
Why this matters
Three things convinced us this is worth working on.
Good data can be spoiled on the way to the answer. The UK Community Infection Survey ran from 2020 to 2023, tested over four million swabs from more than 150,000 households, and cost over half a billion pounds. External modellers could not see the underlying observations, only summarised prevalence estimates. Those estimates became inputs to incidence estimates, which became inputs to reproduction number estimates, which in turn fed analyses of how transmissible and how severe new variants were. At every step the uncertainty was approximated and the previous step’s assumptions were inherited, with no way to check what they cost.
Models do not survive contact with the next outbreak. During COVID-19 there were models bringing together case counts, prevalence surveys, severity data, and hospital occupancy. When mpox arrived in 2022 the data were similar, but contact structure and behaviour now needed representing, and those models could not be adapted. New ones were written from scratch, and because evidence was needed quickly, they fitted to a single data source.
We keep rebuilding the same things. At least seven packages estimate the reproduction number using renewal approaches in Stan. None of them share components, despite overlapping heavily and in some cases sharing authors. The unit of reuse has become the whole model, or the whole codebase, rather than the epidemiological ideas inside it. The cost shows up as expertise that never lands. Wastewater tools have largely been written by people who are not wastewater experts, and a wastewater expert who wants to contribute has no way in short of writing an entire model themselves.
Composable models are a way out of this. If a model is assembled from interchangeable parts, a domain expert can contribute one part without understanding the whole system. Two groups who disagree can also tell whether they disagree about an assumption or about an implementation detail.
What we want from such a system
Before building anything it helps to say what would count as success. This is our first cut, and we would like to be told where it is wrong.
- Carry uncertainty the whole way through. From the processes you cannot see to the data you can, fitting everything together rather than in stages.
- Combine in a principled way. Where things genuinely must be fitted in stages, combine them properly rather than by passing point estimates along.
- Keep the parts separate. Transmission, the priors that drive it, and observation should be separate things, so different people can own them.
- Let models nest inside models. Adding a data source or a process should not mean rewriting the model.
- Support more than one kind of model. These come as renewal processes, compartmental models, agent-based models, and more.
- Make stratification close to free. Age, place, or risk group should not mean a rewrite and a lot of bookkeeping.
- Let a component carry its own priors. Domain knowledge should travel with the component that encodes it.
- Allow incremental adoption. Nobody should have to abandon a working model to try this.
- Stay useful on its own. A component should earn its keep even outside the wider system.
- Use standard interfaces. Parts written independently should still fit together and still propagate uncertainty correctly.
- Specify once, then simulate and fit. The generative story and the fit should not be able to drift apart.
- Be quick to change and easy to inspect. A decision is usually waiting.
Where language models come in
We think composability is what would make language model assisted modelling safe enough to be useful.
Ask a model to write a bespoke several-hundred-line Stan program and there is no unit of correctness. You either trust the whole thing or you do not. If instead a model is a composition of named epidemiological components, each with standard interfaces, its own priors, and its own validation, the job shrinks to choosing and wiring parts. The wiring can be checked automatically, and mistakes surface at the interface rather than in the posterior. The components also carry expert knowledge that a language model would otherwise have to invent, which is exactly where they are weakest.
This is an argument rather than a result. We have not tested it yet.
What EpiAware is
EpiAware is a set of small, interoperable Julia packages rather than a single framework. We are not sure which way of composing models will work best, so we are trying more than one and keeping them interoperable. Some parts build on Turing.jl for full Bayesian inference, and others extend Distributions.jl and are useful on their own. The approaches page describes the routes we are exploring so far.
Where it is today
CensoredDistributions.jl is the most developed. The joint modelling and composition packages are in active development. Each package’s entry says how settled it is.
Other people are working towards the same goal, and we would rather work alongside them than around them. The packages page links to them.
Funding, and the lack of it
We think this is worth doing properly, and we have been applying for funding to do it. So far without success.
Rather than wait, we have started the organisation and begun building in the open, at whatever pace we can manage alongside other work. We are still looking for the support that would let us take it further.
Get involved
If any of this interests you, please get in touch.
- Collaborators are welcome, whether that is code, docs, examples, or a modelling problem to test the approach on.
- If you fund work of this kind, we would like to talk.
- If you know of an opportunity that might fit, please point us at it, or introduce us.
Start a conversation on the epinowcast forum, or see Get involved.