Table functions (TFUN)¶
Table functions (TFUN)¶
# Time-indexed: load tabular data for piecewise-linear interpolation
model.add_table_function("cumNcases", file="case_data.tfun")
# Parameter-indexed (e.g., dose-response)
model.add_table_function("response", file="dose_response.tfun", index="drug_conc")
# Step interpolation (piecewise-constant)
model.add_table_function(
"dose_step", file="dose_response.tfun", index="time", method="step"
)
# From in-memory arrays
model.add_table_function(
"drive", times=[0, 1, 2, 5], values=[0, 0, 1, 5], method="linear"
)
# Introspect
print(model.n_table_functions) # 1
print(model.table_function_names) # ['cumNcases']
Table functions can also be defined in .net files using the tfun() syntax:
begin functions
1 cumNcases() tfun('case_data.tfun') # time-indexed (default)
2 response() tfun('dose.tfun', drug_conc) # parameter-indexed
3 drive() tfun('dose.tfun', time, method=>"step")
4 inline() tfun([0,1,2], [0,10,20], time, method=>"linear")
end functions
.tfun file format (GDAT-style, #-prefixed header required):
# time cumNcases
0 0
1 0
2 1
3 1
4 2
5 5
Column 1: index values (must be monotonically increasing)
Column 2: function values
Interpolation:
linear(default) orstepExtrapolation: constant (hold first/last value beyond endpoints)
Minimum 2 data rows required
Table Functions (TFUN) — Detailed Reference¶
Table functions provide piecewise-linear interpolation from tabular data, useful for time-varying inputs (e.g., experimental forcing, drug dosing).
Three ways to create table functions:
In a
.netfile (parsed automatically by BNGsim):
begin functions
1 cumNcases() tfun('case_data.tfun') # time-indexed
2 response() tfun('dose.tfun', drug_conc) # parameter-indexed
end functions
From a file in Python:
model.add_table_function("cumNcases", file="case_data.tfun")
model.add_table_function("response", file="dose.tfun", index="drug_conc")
From in-memory arrays:
model.add_table_function("drive",
times=[0, 1, 2, 5, 10],
values=[0, 0, 1, 5, 5])
.tfun file format (GDAT-style, two columns, #-prefixed header):
# time cumNcases
0 0
1 0
2 1
3 1
4 2
5 5
6 10
7 20
Requirements:
First line must be a
#-prefixed header (column names; ignored by parser)Column 1: index values — must be monotonically increasing (strictly)
Column 2: function values (any real numbers)
Minimum 2 data rows
Whitespace-separated columns (spaces or tabs)
Interpolation: Linear between data points. Extrapolation: Constant — holds first value below range, last value above range.
Index variable: By default, the table function is indexed by simulation time. Specify a different index with the second argument:
tfun('file.tfun')— indexed bytime(default)tfun('file.tfun', drug_conc)— indexed by parameterdrug_conctfun('file.tfun', A_tot)— indexed by observableA_tottfun('file.tfun', time, method=>"step")— piecewise-constant interpolationtfun([0,1,2], [0,10,20], time)— inline data (no external file)
The index variable is evaluated at each time step, and the table function returns the interpolated value at that index.
Header / index canonicalization (matches BioNetGen’s TfunReader.pm):
the .tfun column-1 header, the column-2 header, and the index name passed
to tfun() are normalized before validation so a single .tfun file works
across BNG-acceptable spellings.
The time index matches case-insensitively:
time,Time,T,TIME, andt()all canonicalize to the model’s time variable.A trailing
()is stripped from both.tfunheader columns and from the index argument, regardless of index kind. So# drug_conc() response()is accepted against atfun('file.tfun', drug_conc)call that targets thedrug_concparameter, and a header of# Time cumNcases()is accepted on a time-indexed tfun.
Wrapper-form tfun(...) inside a larger expression is supported on
both the .net interpreter and the codegen paths:
begin functions
1 f_complex() (tfun('drive.tfun', time) + 5) / k_scale
2 f_combo() tfun([0,1,2], [10,20,40], time) / 10 + offset
end functions
The loader extracts each embedded tfun(...) call into a synthetic
anonymous table function (visible as <bng_func>__tfun<k> in
table_function_names) and rewrites the call site so the wrapping
arithmetic survives untouched into ExprTk evaluation. The codegen path
emits a tfun_eval(tf_id, idx, ctx) callback nested inside the
translated wrapper math. Multiple tfun(...) calls per function body
are supported (each gets its own synthetic name and tf_id); this is a
strict extension of BioNetGen’s own parser, which only stores one
tfunData per expression.
How it works: BNGsim parses tfun() syntax directly in net_file_loader.cpp.
No changes to BNG2.pl are required — users can add tfun() to .net files or use
the Python API.
NFsim XML TFUN format:
Canonical placeholder in
<Expression>is__TFUN_VAL__.File-backed TFUN:
<Function type="TFUN" file="..." ctrName="..." method="linear|step">
Inline TFUN:
<Function type="TFUN" mode="inline" ctrName="..." xData="..." yData="..." method="linear|step">
Validation rules:
xData/yDataCSV values are whitespace-trimmedscientific notation is accepted (e.g.,
1e-3,2.5E+2)xDataandyDatalengths must matchxDatamust be strictly increasing