-
Notifications
You must be signed in to change notification settings - Fork 24
Description
Feature Request: Table Function (TFUN) Support in BNGL
Summary
Add support for table functions (tfun) in the BNGL functions block, enabling users to define piecewise-linear interpolation functions from tabular data files. This would allow empirical data (e.g., time-series measurements, dose-response curves) to be incorporated directly into model functions and rate expressions, and allow simulation results to be compared to data in plots generated from GDAT and SCAN files.
Motivation
Several common modeling scenarios require injecting empirical data into simulations:
- Epidemiological modeling: Cumulative case count data
- Pharmacology: Drug dosing schedules as time-dependent drivers of dynamics
- Dose-response fitting: Experimental dose-response curves for parameter scan comparisons
Currently, users must manually encode tabular data as piecewise if() expressions in the functions block, which is error-prone and impractical for large datasets. NFsim already has partial TFUN support (via XML type="TFUN" attributes), but there is no corresponding BNGL-level syntax and no .net file emission.
Proposed BNGL Syntax
begin functions
# Time-indexed table function (default index = time)
cumNcases() = tfun('case_data.tfun')
# Explicit time index
drug_dose() = tfun('dosing_schedule.tfun', time)
# Parameter-indexed table function (for dose-response / parameter scans)
response() = tfun('dose_response.tfun', drug_conc)
end functions
The second argument (index) specifies which quantity provides the lookup key:
time(ort) — simulation time (default if omitted)- A parameter name — the current value of that parameter (useful for
parameter_scanactions) - An observable or function name — the current evaluated value
File Format (.tfun)
GDAT-style two-column plain text with a #-prefixed header:
# time cumNcases
0 0
1 0
2 1
3 1
4 2
5 5
6 12
7 22
Validation rules:
- First line must be a
#-prefixed header with two column names - Column 1 header must match the index name (
time/t/time()/t()for time-indexed, or the parameter/observable name) - Column 2 header must match the function name being defined
- Column 1 values must be monotonically increasing
- At least 2 data rows required
Interpolation: Piecewise-linear between data points, constant extrapolation beyond endpoints (hold first/last value).
Requested BNG2.pl Changes
-
BNGL parser: Recognize
tfun('filename')andtfun('filename', index_name)syntax in the functions block -
NET file emission: Pass through the
tfun(...)definition to the .net functions block:begin functions 1 cumNcases() tfun('case_data.tfun') 2 response() tfun('dose_response.tfun', drug_conc) end functions -
XML emission (for NFsim): Generate the existing NFsim TFUN XML format:
<Function id="cumNcases" type="TFUN" file="case_data.tfun" ctrName="time"> <Expression>__TFUN__VAL__</Expression> <ListOfReferences> <Reference name="time" type="Observable"/> </ListOfReferences> </Function>