Skip to content

Multi Meal Blueprint

The multi-meal blueprint pairs MultiMealT1DModel with MultiMealT1DData. Use it to twin a portion of data spanning a single day, with multiple labelled meals and a time-of-day insulin sensitivity. It is the most common choice.

Usage

from py_replay_bg.data.multi_meal_t1d_data import MultiMealT1DData
from py_replay_bg.model.multi_meal_t1d import MultiMealT1DModel

rbg_data = MultiMealT1DData(data=df, environment=rbg.environment)

# rbg_data.t_start is the minute-of-day of the first sample.
model = MultiMealT1DModel(u2ss=rbg_data.u2ss, tsteps=rbg_data.tsteps,
                          t_start=rbg_data.t_start)

The data class routes each meal by its cho_label into a dedicated channel. Its input channels (data_to_input) are: meal_B, meal_L, meal_D, meal_S, meal_H, bolus, basal, t_hour, forcing_ip, forcing_ra.

Unknown meal labels are dropped

A meal whose cho_label is not one of B, L, D, S, H (including an empty or missing label) is silently left out of every meal channel, so it never reaches the model.

Structure

The multi-meal blueprint is an expanded version of the single-meal one, sharing the subcutaneous insulin absorption and the glucose–insulin kinetics subsystems, but replacing the single stomach with a multi-stomach system and using a time-varying insulin sensitivity.

Multi-meal blueprint

Oral glucose absorption (multi-stomach)

Each meal type gets its own three-compartment stomach/gut chain:

\[ \begin{cases} \dot{Q}_{sto1_M}(t) = - k_{empt}\cdot Q_{sto1_M}(t) + CHO_M(t-\beta_M) \\ \dot{Q}_{sto2_M}(t) = k_{empt}\cdot Q_{sto1_M}(t) - k_{empt}\cdot Q_{sto2_M}(t)\\ \dot{Q}_{gut_M}(t) = k_{empt}\cdot Q_{sto2_M}(t) - k_{abs_M}\cdot Q_{gut_M}(t) \end{cases} \qquad Ra(t) = f\cdot \sum_{M}k_{abs_M} \cdot Q_{gut_M}(t) \]

where the suffix \(M \in \{B, L, D, S, H\}\) denotes the meal type (breakfast, lunch, dinner, snack, hypo-treatment). Each meal type has its own absorption rate \(k_{abs_M}\). Breakfast, lunch, dinner and snack also have their own delay \(\beta_M\); hypo-treatments have no delay parameter (no beta_H) and enter the stomach immediately.

Time-of-day insulin sensitivity

The insulin action equation uses a time-varying sensitivity \(SI(t)\) to capture intraday variability:

\[ SI(t) = \begin{cases} SI_B & \text{if } 04{:}00 \le t < 11{:}00 \\ SI_L & \text{if } 11{:}00 \le t < 17{:}00 \\ SI_D & \text{otherwise} \end{cases} \]

The model reads the hour of each step from the t_hour input channel (the hour of the corresponding data timestamp), and \(X\) follows \(\dot{X}(t) = -p_2 [X(t) - \frac{SI(t)}{V_I}(I_p(t)-I_{pb})]\).

t_start (the minute-of-day of the first sample, available as rbg_data.t_start) does not select the per-step sensitivity. It matters when chaining segments: it decides which sensitivity rescales the carried-over insulin action X0, and which one get_theta() reports as SI_last for the next segment.

Parameter vector

A typical set of parameters estimated by twinning (the one in Getting Started) is:

\[\boldsymbol{\theta}_{phy} = [\{k_{abs_M}, \beta_M\}_{M\in\{B,L,D,S\}}, k_{empt}, k_{a2}, k_{d}, f, p_2, G_b, S_G, SI_B, SI_L, SI_D]^T\]

So relative to single-meal, the sensitivity SI is replaced by SI_B, SI_L, SI_D, and absorption/delay become per-meal (kabs_B, kabs_L, kabs_D, kabs_S, kabs_H; beta_B, beta_L, beta_D, beta_S). The remaining parameters and their defaults are those of the single-meal blueprint; every SI_* defaults to 10.35e-4 / VG, every kabs_* to 0.012 and every beta_* to 0.

Parameters for events that are not in your data

If your data has no lunch event, kabs_L and beta_L simply cannot be personalized — just leave them out of unknown_parameters_prior and they keep their population defaults. Estimate only the parameters your data can inform.

What can I do with it?

You can create a digital twin from a portion of data that spans a single day, because the equations represent the meals of one day (via \(\{k_{abs_M}, \beta_M\}\)) and a one-day insulin-sensitivity profile. To go beyond a single day, chain multiple daily twins — see Twinning multi-day intervals.

As with single-meal, a cold start puts the insulin and meal compartments at steady state (only glucose is seeded from the first CGM value), so pick a starting point far from the last recorded insulin/meal input. See Choosing Data for Twinning.

Example

A complete multi-meal twinning example lives in example/twin_multi_meal.py. Its unknown_parameters_prior and correlations are the ones shown in Getting Started, except that the kd entry is commented out (so kd keeps its default).