Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 39 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,45 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
## [0.0.6] - 2026-03-16

### Changed (Breaking)
- **`daedalus()` function signature refactored**: second positional argument now takes infection parameters (`infection`) instead of scalar/vector `r0`. Users must pass parameters via `InfectionData` object rather than individual keyword arguments
- **Old interface**: `daedalus(country, r0::Float64; sigma=..., epsilon=..., eta=..., ...)`
- **New interface**: `daedalus(country, infection; npi=..., log_rt=..., time_end=..., increment=..., n_threads=...)`
- Removed all infection-parameter keyword arguments: `sigma`, `p_sigma`, `epsilon`, `rho`, `eta`, `omega`, `gamma_Ia`, `gamma_Is`, `gamma_H`, `nu`
- All epidemiological parameters now encapsulated in `InfectionData` object
- Users customize parameters by fetching `InfectionData` and modifying fields before calling `daedalus()`

### Added
- New dispatch methods for `daedalus()`:
1. String pathogen name: `daedalus(country, "sars-cov-2 delta"; ...)`
2. Single `InfectionData`: `daedalus(country, infection_obj; ...)`
3. Vector `InfectionData`: `daedalus(country, [inf1, inf2, ...]; ...)`
- `extract_infection_params()` helper function to extract and expand epidemiological parameters from `InfectionData`
- `InfectionData` is mutable, allowing users to customize parameters post-fetch: `inf = get_pathogen("sars-cov-2 delta"); inf.r0 = 2.5`
- **Infection names are normalized to lowercase**: all pathogen names are stored and looked up as lowercase strings (e.g., `"sars-cov-2 delta"`, `"influenza 2009"`)

### Migration Guide
```julia
# Old (no longer works):
result = daedalus("Australia", 2.5, sigma=0.217, epsilon=0.58, time_end=200.0)

# New (string pathogen, lowercase names):
result = daedalus("Australia", "sars-cov-2 delta", time_end=200.0)

# New (custom infection):
infection = Daedalus.DataLoader.get_pathogen("sars-cov-2 delta")
infection.r0 = 2.5
result = daedalus("Australia", infection, time_end=200.0)

# New (vector of infections):
infections = [
Daedalus.DataLoader.get_pathogen("sars-cov-2 delta"),
Daedalus.DataLoader.get_pathogen("influenza 2009")
]
results = daedalus("Australia", infections, time_end=200.0)
```

## [0.0.5] - 2026-03-09

Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "Daedalus"
uuid = "05fc9732-d2bf-478b-9a56-f88318f7a02f"
authors = ["Pratik Gupte <pratikgupte16@gmail.com> and contributors"]
version = "0.0.5"
version = "0.0.6"

[deps]
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Pkg.add(url="git@github.com:pratikunterwegs/Daedalus.jl.git")
```julia
using Daedalus

daedalus("Australia", 5.0, time_end=600.0)
result = daedalus("Australia", "sars-cov-2 delta", time_end=600.0)
```

## Related projects
Expand Down
44 changes: 31 additions & 13 deletions docs/Manifest.toml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 21 additions & 7 deletions docs/src/benchmarking.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,19 @@ This section shows various benchmarks.
using Daedalus
using BenchmarkTools

@benchmark daedalus("Australia", 2.5, time_end=600.0)
infection_01 = Daedalus.DataLoader.get_pathogen("sars-cov-2 delta")
infection_01.r0 = 2.5
@benchmark daedalus("Australia", infection_01, time_end=600.0)
```

```@example benchmarking_02
# benchmark for an RTM-exercise run of 100 days
using Daedalus
using BenchmarkTools

@benchmark daedalus("Australia", 2.5, time_end=100.0)
infection_02 = Daedalus.DataLoader.get_pathogen("sars-cov-2 delta")
infection_02.r0 = 2.5
@benchmark daedalus("Australia", infection_02, time_end=100.0)
```

## Effect of logging $R_t$
Expand All @@ -33,7 +37,9 @@ using Daedalus
using BenchmarkTools

# turn off Rt logging and compare with benchmark above
@benchmark daedalus("Australia", 2.5, log_rt=false, time_end=600.0)
infection_rt = Daedalus.DataLoader.get_pathogen("sars-cov-2 delta")
infection_rt.r0 = 2.5
@benchmark daedalus("Australia", infection_rt, log_rt=false, time_end=600.0)
```

## Reactive events
Expand All @@ -47,12 +53,16 @@ using BenchmarkTools

npi = Daedalus.DaedalusStructs.Npi(20000.0, (coef=0.7,));

@benchmark daedalus("Australia", 5.0, npi=npi, time_end=600.0)
infection_re = Daedalus.DataLoader.get_pathogen("sars-cov-2 delta")
infection_re.r0 = 5.0
@benchmark daedalus("Australia", infection_re, npi=npi, time_end=600.0)
```

```@example benchmarking_reactive_event
# shorter duration
@benchmark daedalus("Australia", 5.0, npi=npi, time_end=100.0)
infection_re2 = Daedalus.DataLoader.get_pathogen("sars-cov-2 delta")
infection_re2.r0 = 5.0
@benchmark daedalus("Australia", infection_re2, npi=npi, time_end=100.0)
```

## Timed events
Expand All @@ -69,11 +79,15 @@ timed_npi = Daedalus.DaedalusStructs.TimedNpi(
"three_phase_lockdown"
)

@benchmark daedalus("Australia", 3.0, npi=timed_npi, time_end=600.0)
infection_te = Daedalus.DataLoader.get_pathogen("sars-cov-2 delta")
infection_te.r0 = 3.0
@benchmark daedalus("Australia", infection_te, npi=timed_npi, time_end=600.0)
```

Timed events do not need $R_t$ logging and can be benchmarked without it.

```@example benchmarking_timed_event
@benchmark daedalus("Australia", 3.0, npi=timed_npi, time_end=600.0, log_rt=false)
infection_te2 = Daedalus.DataLoader.get_pathogen("sars-cov-2 delta")
infection_te2.r0 = 3.0
@benchmark daedalus("Australia", infection_te2, npi=timed_npi, time_end=600.0, log_rt=false)
```
14 changes: 8 additions & 6 deletions docs/src/country_data.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,28 +59,30 @@ uk.contact_matrix
```@example pathogen_struct
using Daedalus

delta = Daedalus.DataLoader.get_pathogen("SARS-CoV-2 delta")
delta = Daedalus.DataLoader.get_pathogen("sars-cov-2 delta")

delta
```

## Preparing country inputs for the model

Pass a country name string directly to [`daedalus`](@ref) to run the model with country-specific demography, contacts, and workforce data:
Pass a country name string and a pathogen name to [`daedalus`](@ref) to run the model with country-specific demography, contacts, and workforce data:

```@example country_inputs
using Daedalus

result = daedalus("United Kingdom", 2.5, time_end=600.0)
result = daedalus("United Kingdom", "sars-cov-2 delta", time_end=600.0)
```

You can also pass a [`DataLoader.CountryData`](@ref) struct directly.
This is useful when you want to pre-fetch or modify country data before running the model:
You can also pass a [`DataLoader.CountryData`](@ref) struct directly and customize infection parameters.
This is useful when you want to pre-fetch or modify country or infection data before running the model:

```@example country_inputs
# Pre-fetch country data and pass the struct directly
uk = Daedalus.DataLoader.get_country("United Kingdom")
result2 = daedalus(uk, 2.5, time_end=600.0)
infection = Daedalus.DataLoader.get_pathogen("sars-cov-2 delta")
infection.r0 = 2.5
result2 = daedalus(uk, infection, time_end=600.0)
```

The `Data` sub-module also exposes lower-level functions for inspecting or manipulating the country arrays directly.
Expand Down
25 changes: 20 additions & 5 deletions docs/src/ensemble.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,22 @@ Better functionality for working with ensemble outputs, using the inbuilt DE.jl

## Basic ensemble run

Pass a `Vector{Float64}` as the `r0` argument instead of a scalar value:
Pass a `Vector{InfectionData}` with different R0 values:

```@example ensemble_basic
using Daedalus
using Plots

# Run model with three different R0 values
r0_values = [1.5, 2.5, 3.5]
results = daedalus("Australia", r0_values, time_end=600.0);
infections = [
Daedalus.DataLoader.get_pathogen("sars-cov-2 delta"),
Daedalus.DataLoader.get_pathogen("sars-cov-2 delta"),
Daedalus.DataLoader.get_pathogen("sars-cov-2 delta")
]
infections[1].r0 = 1.5
infections[2].r0 = 2.5
infections[3].r0 = 3.5
results = daedalus("Australia", infections, time_end=600.0);

# Each result contains: sol, saves, npi, r0
println("Number of results: ", length(results))
Expand Down Expand Up @@ -97,7 +104,11 @@ npi = Daedalus.DaedalusStructs.Npi(10000.0, (coef=0.5,))

# Run ensemble with same NPI applied to all R0 values
r0_range = [1.5, 2.0, 2.5, 3.0, 3.5]
results_with_npi = daedalus("Australia", r0_range, npi=npi, time_end=600.0)
infections_npi = [Daedalus.DataLoader.get_pathogen("sars-cov-2 delta") for _ in r0_range]
for (i, r0) in enumerate(r0_range)
infections_npi[i].r0 = r0
end
results_with_npi = daedalus("Australia", infections_npi, npi=npi, time_end=600.0)
```

## Large-scale parameter sweeps
Expand All @@ -107,7 +118,11 @@ For broader sensitivity analyses, you can define finer-grained R0 ranges:
```@example ensemble_basic
# Fine-grained sweep from 1.0 to 5.0 in 0.5 increments
r0_sweep = collect(1.0:0.5:5.0)
results_sweep = daedalus("Australia", r0_sweep, time_end=300.0);
infections_sweep = [Daedalus.DataLoader.get_pathogen("sars-cov-2 delta") for _ in r0_sweep]
for (i, r0) in enumerate(r0_sweep)
infections_sweep[i].r0 = r0
end
results_sweep = daedalus("Australia", infections_sweep, time_end=300.0);

# NOTE: add plot of infectious or exposed
```
Expand Down
8 changes: 6 additions & 2 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ using Daedalus
using Plots

# pump up r0 to get peak within 50 days
data = daedalus("Canada", 5.0, time_end=600.0);
infection = Daedalus.DataLoader.get_pathogen("sars-cov-2 delta")
infection.r0 = 5.0
data = daedalus("Canada", infection, time_end=600.0);

# plot exposed group
times = Daedalus.Outputs.get_times(data)
Expand Down Expand Up @@ -66,7 +68,9 @@ using Daedalus
using Plots

# Run the model using UK demography and contact patterns
data_uk = daedalus("United Kingdom", 2.5, time_end=600.0)
infection_uk = Daedalus.DataLoader.get_pathogen("sars-cov-2 delta")
infection_uk.r0 = 2.5
data_uk = daedalus("United Kingdom", infection_uk, time_end=600.0)

times_uk = Daedalus.Outputs.get_times(data_uk)
exposed_uk = Daedalus.Outputs.get_values(data_uk, "E", 1)
Expand Down
16 changes: 13 additions & 3 deletions docs/src/npis.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,14 @@ using Plots
hosp_threshold=20000.0
a = Daedalus.DaedalusStructs.Npi(hosp_threshold, (coef=0.7,));

data = daedalus("Australia", 3.0, npi=a, time_end=600.0);
data_default = daedalus("Australia", 3.0, time_end=600.0);
# Create infection data for both runs
infection = Daedalus.DataLoader.get_pathogen("sars-cov-2 delta")
infection.r0 = 3.0
infection_default = Daedalus.DataLoader.get_pathogen("sars-cov-2 delta")
infection_default.r0 = 3.0

data = daedalus("Australia", infection, npi=a, time_end=600.0);
data_default = daedalus("Australia", infection_default, time_end=600.0);

# plot new hosp over time
iHosp = Daedalus.Constants.get_indices("H")
Expand Down Expand Up @@ -61,7 +67,11 @@ timed_npi = Daedalus.DaedalusStructs.TimedNpi(
"three_phase_lockdown"
)

data = daedalus("Australia", 3.0, npi=timed_npi, time_end=600.0);
# Create infection data
infection_timed = Daedalus.DataLoader.get_pathogen("sars-cov-2 delta")
infection_timed.r0 = 3.0

data = daedalus("Australia", infection_timed, npi=timed_npi, time_end=600.0);

# get exposed
iExpo = Daedalus.Constants.get_indices("E")
Expand Down
Loading
Loading