APTmodel¶
This class stores information regarding the model. Its functions aid the user in defining the attributes of the model. APTmodel will take the information and generate compilable C++ code in a subdirectory.
Instantiation:
import aptmodel as apt
model = apt.aptmodel()
The following are required if Sundials and TRNG directories are not set in your PATH enviornment. It is highly recommended to define these values anyway. In the event that the generated C++ code fails to compile, the user is then able to rule out the possibility of library not found errors.
Library Include Path(s)¶
set_include_path(*args)
Point APTmodel towards the include directories for Sundials and TRNG. Highly recommended.
Args:
- *args: Variable length argument of strings: dir1, dir2, … dirN, each containing a directory path
Example:
model.set_include_path('/usr/local/include', '/home/user1/sundials/installdir')
Library Lib Path(s)¶
set_lib_path(*args)
Point APTmodel towards the lib directories for Sundials and TRNG. Highly recommended.
Args:
- *args: Variable length argument of strings: dir1, dir2, … dirN, each containing a directory path
Example:
model.set_lib_path('/usr/local/include', '/home/user1/sundials/installdir')
Note
dir1, dir2, … should be absolute paths
User-specified Model¶
The following documents how to define a user-supplied model into APTmodel. The user-supplied model must be an ODE parameter fitting problem. APT-MCMC can handle any objective function, but it would be up to the user to code in specialized objective functions in C++.
In order to define a model, the user should (in order):
- Adding Parameters
- Adding States
- Defining ODEs
- Adding Experimental Data
- Setting Output directory
- Generating APT-MCMC simulation
A complete example may be found in the Tutorial section.
Adding Parameters¶
add_par(parname, LB, UB)¶
Add a parameter along with its lower bound and upper bound. A uniform distribution bounded at [LB, UB] will be established for this parameter’s prior. This can be used in conjunction with load_params_from_csv(filename, verbose=True). At least 1 parameter is required.
Args:
- parname (str): Name of your parameter.
- LB (float): Lower bound for your parameter.
- UB (float): Upper bound for your parameter.
Example:
model.add_par('k1', 0, 5)
load_params_from_csv(filename, verbose=True)¶
Loads parameters from a csv file. If the user has many parameters, the user may wish to load them from a csv file rather than having many, many lines of add_par(parname, LB, UB). The function autodetects if the csv file has headers. This can be used in conjunction with add_par(parname, LB, UB). At least 1 parameter is required.
Args:
- filename (str): Name of the csv file, including the .csv extension, if it is in the Python working directory. Otherwise, specify the relative or absolute directory.
- verbose (bool): If true (default), display each row as it is read from the file.
Raises:
- NameError if the csv file contains non-numbers (other than a header, which is autodetected).
Example:
model.load_params_from_csv('model4_pars.csv', verbose=False)
showpar()¶
Show the currently loaded parameters in APTmodel. It is recommended to do this before the model generation step to ensure everything is correct.
Example:
model.showpar()
Adding States¶
add_states(*args)¶
Add states to the APTmodel. This can be called multiple times in order to keep adding states. At least 1 state is required
Args:
- *args (str): Variable length argument of strings, one for each state the user wishes to add.
Example:
model.add_states('Ca', 'Cb')
showstates()¶
Show the currently loaded states in APTmodel. It is recommended to do this before the model generation step to ensure everything is correct.
Example:
model.showstates()
Defining ODEs¶
ODE[s].set(expr)
Define the ODE equation for state s. The expression needs to be written in C/C++ math. Expressions are very similar to that of Python, but the most significant difference is the power function:
pow(x,y). Required for each defined stateNo error checking will be performed; this string is copied 1:1 into C++ source code. Ensure this is correct! The user is advised to brush up on how mathematical expressions work in C/C++.
Args:
- s (str): String refering to state s. s must have been defined earlier in Adding States.
- expr (str): Mathematical expression in C/C++ that describes the ODE for s.
Note
The following custom functions are built-in for user convenience:
- hill(a,b) = \(\frac{a}{a+b}\)
- hilln(a,n,b) = \(\frac{a^n}{b^n + a^n}\)
- heavy(z) = \(\frac{1}{10^{-10z}}\)
Example:
\[\frac{dC_a}{dt} = -k_1 C_a^2\]model.ODE['Ca'] = '-k1 * pow(Ca,2)'
ODE[s].add_helper(expr)
Define an unlimited amount of helper variables for the user’s edification for state s. Any math needs to be compatible with C/C++ math, but including type declarations or the ; prefix is not necessary.
Args:
- s (str): String refering to state s. s must have been defined earlier in Adding States.
- expr(str): An expression defining a helper variable.
The order that these helper variables appear in the C++ file are determined by the order with which the user defined states in Adding States. Furthermore, helper variables will always show up (in the order they are defined) before the ODE expression is defined in the C++ file.
There is a Constant state, ‘Constants’, available for the user. These constants will always be defined first in the C++ file. You may define any static constants as such:
model.ODE['Constants'].add_helper('myconst = 4.3') model.ODE['Constants'].add_helper('myconst2 = Ca * 1.2') # states can be used also (Ca is the state in this example)
Note
In order to fit patient-specific parameters or constants, see Experiment-Specific Parameters or Constants.
Adding Experimental Data¶
add_experiment(APTexpr_obj)
Add an APTexperiment object into the model. APTexperiment objects store experimental data and makes APTmodel fit the ODE model to each APTexperiment simultaneously. See APTexperiment for more details. At least 1 experiment is required.
Args:
- APTexpr_obj (APTexperiment object): An APTexperiment object containing data, initial conditions, and/or infusions.
Example:
- model = apt.aptmodel()
- model.add_experiment(experiment1) model.add_experiment(experiment2)
Setting Output directory¶
output(dir)
Set the output directory for APTmodel to generate the C++ files in. By default, it will be created in
./Output. APTmodel will create the directory if it doesn’t exist and will overwrite files if the directory does exist. Therefore, it is recommended to set the output directory to something different for each simulation rather than leave it to the default values.Args:
- dir (str): Name of the directory to output C++ files to. No
./or trailing/is necessary.Example:
model = apt.aptmodel() ... # Define model model.output('Model4')
Generating APT-MCMC simulation¶
generate(options)
Generate a the C++ source code for an APT-MCMC simulation for the user-defined problem. An APToptions file is required as input in order to define the APT-MCMC options and settings necessary for this generation.
Note
A lot of pre-checking and error handling is covered by this function, but the responsibility is up to the user to ensure that all required model inputs are defined and all model definitions are correct. Any errors not detected by
generatewill probably show up during the compilation step.Args:
- options (APToptions object): Options for APT-MCMC
Example:
- model = apt.aptmodel()
- … # Define model options = apt.aptoptions() # Use default options model.generate(options)
Advance Use Cases¶
Infusions¶
If any of your APTexperiments have infusions in them, they will not be recognized unless the infusion toggle is turned on to True.
enable_infusions(dict)
Turn on the infusion toggle switch in APTmodel so the generation step will be able to use the appropriate source files to handle the overhead associated with solving ODEs with infusions. The user is responsible for providing a dictionary containing infusion names. These names must match the ones used when defining ODEs. Multiple runs of this function will overwrite the previous dictionary.
Args:
- dict (dictionary): A dictionary with key-pair values as Infusion Number:Infusion Name. Keys must begin with 0 and increment by 1, although it does not have to be in order. Dictionaries with skipped key values
eg 0,1,3will not be accepted.Example:
model = apt.aptmodel() model.enable_infusions({0:'infusion_Ca', 1:'infusion_Cb'}) model.ODE['Ca'].set('-k1*Ca + infusion_Ca') model.ODE['Cb'].set('k1*Ca - k2*Cb + infusion_Cb')
Experiment-Specific Parameters or Constants¶
Suppose you have some constants or parameters that depends per experiment. An example would be a patient-specific constant or a patient-specific parameter.
add_per_experiment_par(name, mydict)
Let APTmodel know that parameter name is experiment-dependent and to use the parameters listed in mydict.
Args:
- name (str): Name of the parameter that is experimentally-dependent. This is the parameter name that you would use in defining your model ODEs.
- mydict (dict): A dictionary where keys are each name of your experiments and the items are the parameter pertaining to each experiment. {experimentname:parametername}
Example:
model = apt.aptmodel() model.ODE['Ca'].set('-k1 * Ca') model.add_par('k1_exp1',0,3) model.add_par('k1_exp2',1,2) experiment1 = apt.experiment('Exp1') experiment2 = apt.experiment('Exp2') ... # Add data to experiment1 and experiment2 model.add_per_experiment_par('k1', {'Exp1':'k1_exp1', 'Exp2':'k1_exp2'})For a working example, see example file experimental_parameters_example.py.
- add_per_experiment_constant(name, mydict)
Let APTmodel know that constant name is experiment-dependent and to take on the values listed in mydict.
Args:
- name (str): Name of the constant that is experimentally-dependent. This is the constant name that you would use in defining your model ODEs.
- mydict (dict): A dictionary where keys are each name of your experiments and the items are the values pertaining to each experimental constant. {experimentname:value}
Example:
model = apt.aptmodel() model.ODE['Ca'].set('-k1 * Ca * myconst') experiment1 = apt.experiment('Exp1') experiment2 = apt.experiment('Exp2') # Add data to experiment1 and experiment2 (not shown) model.add_per_experiment_constant('myconst', {'Exp1':5, 'Exp2':4})
Benchmark Model¶
This class tells APTmodel to use a pre-defined benchmark function.
listbenchmarks()
Prints a list of available benchmark functions that APTmodel can autogenerate. Some benchmarks are infinitely scalable in parameter dimensionality and will be marked appropriately. Note the number of the desired benchmark function.
genbenchmark(function_no, options=aptoptions(), npar=0)
Generates C++ code for the specified benchmark function into the output directory using the provided options and parameter dimensionality (if applicable).
Args:
- function_no (int): A value pertaining to the desired function obtained from in-listbench.
- options (APToptions object): Options for the simulation
- npar (int): Parameter dimensionality for the selected function. Only required if the problem is scalable; ignored otherwise.
The recommended procedure for benchmark generation is:
- Initialize an APTmodel object
- List the benchmarks and take note of the number of your desired function.
- Set the APTmodel output directory.
- Set the options.
- Run
genbenchmark.
Example:
import aptmodel as apt
model = apt.aptmodel()
model.listbenchmarks()
model.output('AlpineBenchmark')
options = apt.aptoptions(maxThr=8, nSwap = 1e4)
model.genbenchmark(3, options, 5) # Run alpine benchmark