Phenotype Models¶
simACE maps each individual's continuous liability \(L = A + C + E\) to an
observable affection status (and, for the time-to-event families, an
age of onset) via a configurable phenotype model. The model family
and its parameters are set per trait under the phenotype.trait1 and
phenotype.trait2 sub-blocks of the scenario configuration; the
overall configuration schema is described in
Configuration.
Schema¶
phenotype:
trait1:
model: frailty # frailty | cure_frailty | adult | first_passage
params: # model-specific (see tables below)
distribution: weibull
scale: 2160
rho: 0.8
beta: 1.0 # liability coefficient
beta_sex: 0.0 # additive sex effect (sex == 1 is male)
trait2:
...
prevalence is a property of the threshold-based families (adult,
cure_frailty) only and lives inside their params block:
phenotype:
trait1:
model: adult
params:
method: ltm
cip_x0: 50
cip_k: 0.2
prevalence: 0.10 # required for adult / cure_frailty
beta: 1.0
frailty and first_passage reject prevalence outright — case
fraction emerges from the hazard for those families and a target
prevalence is meaningless.
| Key | Type | Description |
|---|---|---|
model |
str | Phenotype model family (see below). |
params |
dict | Model-specific (see tables below). For adult / cure_frailty, includes the required prevalence. |
beta |
float | Liability coefficient. For frailty / cure_frailty this multiplies the latent liability into the log-hazard; for first_passage it scales the drift; for adult it scales the standardized liability used in the threshold mapping. |
beta_sex |
float | Additive sex effect, applied in the same units as beta. |
Model families¶
frailty— proportional-hazards frailty. Liability scales the baseline hazard via \(z = \exp(\beta\,L)\). Given sufficient time every individual eventually onsets. Requiresparams.distributionand the hazard parameters of that distribution. Does not acceptparams.prevalence.cure_frailty— mixture of a susceptible fraction (frailty) and an immune fraction (never onsets). The susceptible fraction is sized fromparams.prevalence. Sameparams.distributionschema asfrailty, withprevalenceadded.adult— ADuLT liability-threshold variants (Pedersen et al., 2023). Requiresparams.method\(\in\) {ltm,cox}, the cumulative-incidence parameterscip_x0,cip_k, andparams.prevalence.first_passage— first-passage-time of a Brownian motion with drift. Requiresparams.driftandparams.shape. Does not acceptparams.prevalence.
Hazard distributions for frailty / cure_frailty¶
Set under params.distribution:
| Distribution | Required params |
|---|---|
weibull |
scale, rho |
exponential |
rate |
gompertz |
rate, gamma |
lognormal |
mu, sigma |
loglogistic |
scale, shape |
gamma |
shape, scale |
The registry is in simace.phenotyping.hazards.BASELINE_HAZARDS; each
entry maps a distribution name to a vectorized inverter.
ADuLT methods for adult¶
Set under params.method:
| Method | Required params | Description |
|---|---|---|
ltm |
cip_x0, cip_k, prevalence |
Deterministic liability-threshold with logistic cumulative-incidence proportion. |
cox |
cip_x0, cip_k, prevalence |
Proportional hazards with Weibull noise and rank-based CIP-to-age mapping. |
first_passage params¶
| Param | Description |
|---|---|
drift |
Drift rate of the latent random walk. Negative drift caps the susceptible fraction (cure-like behaviour); non-negative drift gives an eventually-affected population. |
shape |
Boundary parameter governing the time scale of first passage. |
Parallel simple_ltm output¶
Independently of the configured family, every scenario produces a
parallel phenotype.simple_ltm.parquet output by applying
simace.phenotyping.threshold.apply_threshold to liability1 /
liability2. For adult / cure_frailty traits this path uses the
configured params.prevalence; for frailty / first_passage traits
it falls back to the documented defaults (0.10, 0.20). The cut respects
the global standardize flag (so standardize: per_generation makes the
benchmark prevalence-preserving per generation; global matches the
cohort-wide z-score).
Standardization¶
The global standardize flag (none / global / per_generation)
controls how liability is normalised before phenotyping. The four
hazard-bearing families additionally accept a per-trait override
standardize_hazard inside params:
phenotype:
trait1:
model: cure_frailty
params:
distribution: weibull
scale: 2160
rho: 0.8
prevalence: 0.10
standardize_hazard: per_generation # overrides global standardize
# for the hazard step only
beta: 1.0
When omitted, standardize_hazard inherits the global standardize
value. threshold and adult with method: ltm reject the field —
they have no separate hazard step. See ACE Model §
Standardisation for the
per-model routing table and cure_frailty's two-knob behaviour.
Prevalence¶
For adult / cure_frailty, three forms of params.prevalence are
accepted:
- Scalar (e.g.
0.10) — same prevalence for every individual. - Per-generation dict (e.g.
{2: 0.03, 3: 0.05, 4: 0.08, 5: 0.12}) — prevalence varies across generations; every phenotyped generation must have an entry. - Sex-specific dict (e.g.
{female: 0.08, male: 0.12}) — prevalence differs by sex; each sex value may itself be a scalar or a per-generation dict.
Adding a new phenotype model¶
Each model family is a frozen dataclass under simace/phenotyping/models/
that subclasses PhenotypeModel. To add a fifth family:
- Write
simace/phenotyping/models/my_model.pyexposing a classMyModel(PhenotypeModel)with typed parameter fields and the abstract methods (from_config,add_cli_args,from_cli,cli_flag_attrs,to_params_dict,simulate). - Validate parameters in
__post_init__.from_configandfrom_clishould wrap anyValueError/TypeErrorfrom construction with trait context via thewrap_trait_errorhelper. - Import the class in
simace/phenotyping/models/__init__.pyand add"my_model": MyModelto theMODELSdict.
That's the entire registration surface — no decorator, no auto-discovery.
The dispatcher in simace.phenotyping.phenotype._simulate_one_trait,
the validator in simace.config._validate_phenotype_config, and the
CLI in simace.phenotyping.phenotype.cli all read from MODELS and
pick up the new family automatically.