Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow option to not build Julia model files #54

Merged
merged 3 commits into from
Jun 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/src/Boehm.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ To get started, we first need to read the PEtab files into Julia. This can be ea
2. The observable PEtab table is translated into Julia functions that compute observables ($h$), noise parameter ($\sigma$), and initial values ($u_0$).
3. To compute gradients via adjoint sensitivity analysis or forward sensitivity equations, the derivatives of $h$ and $\sigma$ are calculated symbolically with respect to the ODE-model states ($u$) and parameters.

All of these steps happen automatically, and you can find the resulting files in the *dirYamlFile/Julia_model_files/* directory. By default, the `readPEtabModel` function does not rebuild the Julia files if they already exist, so it saves time.
All of these steps happen automatically, and you can find the resulting files in the *dirYamlFile/Julia_model_files/* directory assuming (as default) `writeToFile=true`, otherwise no model files are written to disk. By default, the `readPEtabModel` function does not rebuild the Julia files if they already exist to save time.

```julia
using PEtab
Expand Down
101 changes: 57 additions & 44 deletions src/Create_PEtab_model.jl

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/PEtab.jl
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ include(joinpath("Show.jl"))
@setup_workload begin
pathYAML = joinpath(@__DIR__, "..", "test", "Test_model3", "Test_model3.yaml")
@compile_workload begin
petabModel = readPEtabModel(pathYAML, verbose=false, forceBuildJuliaFiles=true)
petabModel = readPEtabModel(pathYAML, verbose=false, forceBuildJuliaFiles=true, writeToFile=false)
petabProblem = createPEtabODEProblem(petabModel, verbose=false)
petabProblem.computeCost(petabProblem.θ_nominalT)
end
Expand Down
94 changes: 68 additions & 26 deletions src/Process_PEtab_files/Observables/Create_h_sigma_derivatives.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ function createDerivative_σ_h_File(modelName::String,
stateMap,
SBMLDict::Dict;
jlFile::Bool=false,
customParameterValues::Union{Nothing, Dict}=nothing)
customParameterValues::Union{Nothing, Dict}=nothing,
writeToFile::Bool=true)

pODEProblemNames = string.(parameters(odeSystem))
modelStateNames = replace.(string.(states(odeSystem)), "(t)" => "")
Expand All @@ -33,9 +34,10 @@ function createDerivative_σ_h_File(modelName::String,
# Indices for keeping track of parameters in θ
θ_indices = computeIndicesθ(parameterInfo, measurementInfo, odeSystem, parameterMap, stateMap, experimentalConditions)

create∂h∂_Function(modelName, dirJulia, modelStateNames, parameterInfo, pODEProblemNames, string.(θ_indices.θ_nonDynamicNames), observablesData, SBMLDict)

create∂σ∂_Function(modelName, dirJulia, parameterInfo, modelStateNames, pODEProblemNames, string.(θ_indices.θ_nonDynamicNames), observablesData, SBMLDict)
∂h∂uStr, ∂h∂pStr = create∂h∂_Function(modelName, dirJulia, modelStateNames, parameterInfo, pODEProblemNames, string.(θ_indices.θ_nonDynamicNames), observablesData, SBMLDict, writeToFile)
∂σ∂uStr, ∂σ∂pStr = create∂σ∂_Function(modelName, dirJulia, parameterInfo, modelStateNames, pODEProblemNames, string.(θ_indices.θ_nonDynamicNames), observablesData, SBMLDict, writeToFile)

return ∂h∂uStr, ∂h∂pStr, ∂σ∂uStr, ∂σ∂pStr
end


Expand All @@ -59,9 +61,12 @@ function create∂h∂_Function(modelName::String,
pODEProblemNames::Vector{String},
θ_nonDynamicNames::Vector{String},
observablesData::CSV.File,
SBMLDict::Dict)
SBMLDict::Dict,
writeToFile::Bool)

io = open(dirModel * "/" * modelName * "_D_h_sd.jl", "w")
pathSave = joinpath(dirModel, modelName * "_D_h_sd.jl")
io1 = IOBuffer()
io2 = IOBuffer()

modelStateStr, pODEProblemStr, θ_nonDynamicStr = createTopOf∂h∂_Function(modelStateNames, pODEProblemNames,
θ_nonDynamicNames, observablesData)
Expand Down Expand Up @@ -122,21 +127,39 @@ function create∂h∂_Function(modelName::String,
end


write(io, modelStateStr)
write(io, pODEProblemStr)
write(io, θ_nonDynamicStr)
write(io, "\n")
write(io, "function compute_∂h∂u!(u, t::Real, pODEProblem::AbstractVector, θ_observable::AbstractVector,
if writeToFile == true
write(io1, modelStateStr)
write(io1, pODEProblemStr)
write(io1, θ_nonDynamicStr)
write(io1, "\n")
end
write(io1, "function compute_∂h∂u!(u, t::Real, pODEProblem::AbstractVector, θ_observable::AbstractVector,
θ_nonDynamic::AbstractVector, observableId::Symbol, parameterMap::θObsOrSdParameterMap, out) \n")
write(io, uObservebleStr)
write(io, "end\n\n")
write(io1, uObservebleStr)
write(io1, "end")
∂h∂uStr = String(take!(io1))
if writeToFile
strWrite = ∂h∂uStr * "\n\n"
open(pathSave, "w") do f
write(f, strWrite)
end
end

write(io, "function compute_∂h∂p!(u, t::Real, pODEProblem::AbstractVector, θ_observable::AbstractVector,
write(io2, "function compute_∂h∂p!(u, t::Real, pODEProblem::AbstractVector, θ_observable::AbstractVector,
θ_nonDynamic::AbstractVector, observableId::Symbol, parameterMap::θObsOrSdParameterMap, out) \n")
write(io, pObservebleStr)
write(io, "end\n\n")
write(io2, pObservebleStr)
write(io2, "end")
∂h∂pStr = String(take!(io2))
if writeToFile
strWrite = ∂h∂pStr * "\n\n"
open(pathSave, "a") do f
write(f, strWrite)
end
end
close(io1)
close(io2)

close(io)
return ∂h∂uStr, ∂h∂pStr
end


Expand Down Expand Up @@ -230,9 +253,12 @@ function create∂σ∂_Function(modelName::String,
pODEProblemNames::Vector{String},
θ_nonDynamicNames::Vector{String},
observablesData::CSV.File,
SBMLDict::Dict)
SBMLDict::Dict,
writeToFile::Bool)

io = open(dirModel * "/" * modelName * "_D_h_sd.jl", "a")
pathSave = joinpath(dirModel, modelName * "_D_h_sd.jl")
io1 = IOBuffer()
io2 = IOBuffer()

observableIds = string.(observablesData[:observableId])
pObservebleStr = ""
Expand Down Expand Up @@ -287,15 +313,31 @@ function create∂σ∂_Function(modelName::String,
pObservebleStr *= "\t\t" * "return nothing\n" * "\tend\n\n"
end

write(io, "function compute_∂σ∂σu!(u, t::Real, θ_sd::AbstractVector, pODEProblem::AbstractVector, θ_nonDynamic::AbstractVector,
write(io1, "function compute_∂σ∂σu!(u, t::Real, θ_sd::AbstractVector, pODEProblem::AbstractVector, θ_nonDynamic::AbstractVector,
parameterInfo::ParametersInfo, observableId::Symbol, parameterMap::θObsOrSdParameterMap, out) \n")
write(io, uObservebleStr)
write(io, "end\n\n")
write(io1, uObservebleStr)
write(io1, "end")
∂σ∂σuStr = String(take!(io1))
if writeToFile == true
strWrite = ∂σ∂σuStr * "\n\n"
open(pathSave, "a") do f
write(f, strWrite)
end
end

write(io, "function compute_∂σ∂σp!(u, t::Real, θ_sd::AbstractVector, pODEProblem::AbstractVector, θ_nonDynamic::AbstractVector,
write(io2, "function compute_∂σ∂σp!(u, t::Real, θ_sd::AbstractVector, pODEProblem::AbstractVector, θ_nonDynamic::AbstractVector,
parameterInfo::ParametersInfo, observableId::Symbol, parameterMap::θObsOrSdParameterMap, out) \n")
write(io, pObservebleStr)
write(io, "end\n\n")
write(io2, pObservebleStr)
write(io2, "end")
∂σ∂σpStr = String(take!(io2))
if writeToFile == true
strWrite = ∂σ∂σpStr * "\n\n"
open(pathSave, "a") do f
write(f, strWrite)
end
end

close(io)
close(io1)
close(io2)
return ∂σ∂σuStr, ∂σ∂σpStr
end
77 changes: 57 additions & 20 deletions src/Process_PEtab_files/Observables/Create_u0_h_sigma.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ function create_σ_h_u0_File(modelName::String,
stateMap,
SBMLDict::Dict;
jlFile::Bool=false,
customParameterValues::Union{Nothing, Dict}=nothing)
customParameterValues::Union{Nothing, Dict}=nothing,
writeToFile::Bool=true)

pODEProblemNames = string.(parameters(odeSystem))
modelStateNames = replace.(string.(states(odeSystem)), "(t)" => "")
Expand All @@ -38,14 +39,16 @@ function create_σ_h_u0_File(modelName::String,
# Indices for keeping track of parameters in θ
θ_indices = computeIndicesθ(parameterInfo, measurementInfo, odeSystem, parameterMap, stateMap, experimentalConditions)

create_h_Function(modelName, dirJulia, modelStateNames, parameterInfo, pODEProblemNames,
string.(θ_indices.θ_nonDynamicNames), observablesData, SBMLDict)
hStr = create_h_Function(modelName, dirJulia, modelStateNames, parameterInfo, pODEProblemNames,
string.(θ_indices.θ_nonDynamicNames), observablesData, SBMLDict, writeToFile)

create_u0_Function(modelName, dirJulia, parameterInfo, pODEProblemNames, stateMap, inPlace=true)
u0!Str = create_u0_Function(modelName, dirJulia, parameterInfo, pODEProblemNames, stateMap, writeToFile, inPlace=true)

create_u0_Function(modelName, dirJulia, parameterInfo, pODEProblemNames, stateMap, inPlace=false)
u0Str = create_u0_Function(modelName, dirJulia, parameterInfo, pODEProblemNames, stateMap, writeToFile, inPlace=false)

create_σ_Function(modelName, dirJulia, parameterInfo, modelStateNames, pODEProblemNames, string.(θ_indices.θ_nonDynamicNames), observablesData, SBMLDict)
σStr = create_σ_Function(modelName, dirJulia, parameterInfo, modelStateNames, pODEProblemNames, string.(θ_indices.θ_nonDynamicNames), observablesData, SBMLDict, writeToFile)

return hStr, u0!Str, u0Str, σStr
end


Expand All @@ -69,9 +72,11 @@ function create_h_Function(modelName::String,
pODEProblemNames::Vector{String},
θ_nonDynamicNames::Vector{String},
observablesData::CSV.File,
SBMLDict::Dict)
SBMLDict::Dict,
writeToFile::Bool)

io = open(dirModel * "/" * modelName * "_h_sd_u0.jl", "w")
io = IOBuffer()
pathSave = joinpath(dirModel, modelName * "_h_sd_u0.jl")
modelStateStr, θ_dynamicStr, θ_nonDynamicStr, constantParametersStr = createTopOfFunction_h(modelStateNames, parameterInfo,
pODEProblemNames, θ_nonDynamicNames)

Expand All @@ -96,17 +101,27 @@ function create_h_Function(modelName::String,
end

# Create h function
write(io, modelStateStr)
write(io, θ_dynamicStr)
write(io, θ_nonDynamicStr)
write(io, constantParametersStr)
write(io, "\n")
if writeToFile == true
write(io, modelStateStr)
write(io, θ_dynamicStr)
write(io, θ_nonDynamicStr)
write(io, constantParametersStr)
write(io, "\n")
end
write(io, "function compute_h(u::AbstractVector, t::Real, pODEProblem::AbstractVector, θ_observable::AbstractVector,
θ_nonDynamic::AbstractVector, parameterInfo::ParametersInfo, observableId::Symbol,
parameterMap::θObsOrSdParameterMap)::Real \n")
write(io, observableStr)
write(io, "end\n\n")
write(io, "end")
hStr = String(take!(io))
if writeToFile == true
strWrite = hStr * "\n\n"
open(pathSave, "w") do f
write(f, strWrite)
end
end
close(io)
return hStr
end


Expand Down Expand Up @@ -176,10 +191,12 @@ function create_u0_Function(modelName::String,
dirModel::String,
parameterInfo::ParametersInfo,
pODEProblemNames::Vector{String},
stateMap;
stateMap,
writeToFile::Bool;
inPlace::Bool=true)

io = open(dirModel * "/" * modelName * "_h_sd_u0.jl", "a")
pathSave = joinpath(dirModel, modelName * "_h_sd_u0.jl")
io = IOBuffer()

if inPlace == true
write(io, "function compute_u0!(u0::AbstractVector, pODEProblem::AbstractVector) \n\n")
Expand Down Expand Up @@ -230,8 +247,17 @@ function create_u0_Function(modelName::String,
write(io, modelStateStr)
end

write(io, "\nend\n\n")
write(io, "\nend")
u0Str = String(take!(io))
if writeToFile == true
strWrite = u0Str * "\n\n"
open(pathSave, "a") do f
write(f, strWrite)
end
end
close(io)

return u0Str
end


Expand All @@ -255,9 +281,11 @@ function create_σ_Function(modelName::String,
pODEProblemNames::Vector{String},
θ_nonDynamicNames::Vector{String},
observablesData::CSV.File,
SBMLDict::Dict)
SBMLDict::Dict,
writeToFile::Bool)

io = open(dirModel * "/" * modelName * "_h_sd_u0.jl", "a")
pathSave = joinpath(dirModel, modelName * "_h_sd_u0.jl")
io = IOBuffer()

# Write the formula for standard deviations to file
observableIds = string.(observablesData[:observableId])
Expand All @@ -282,6 +310,15 @@ function create_σ_Function(modelName::String,
write(io, "function compute_σ(u::AbstractVector, t::Real, θ_sd::AbstractVector, pODEProblem::AbstractVector, θ_nonDynamic::AbstractVector,
parameterInfo::ParametersInfo, observableId::Symbol, parameterMap::θObsOrSdParameterMap)::Real \n")
write(io, observableStr)
write(io, "end")
write(io, "\nend")
σStr = String(take!(io))
if writeToFile == true
strWrite = σStr * "\n\n"
open(pathSave, "a") do f
write(f, strWrite)
end
end
close(io)

return σStr
end
25 changes: 14 additions & 11 deletions src/Process_PEtab_files/Process_callbacks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ function createCallbacksForTimeDepedentPiecewise(odeSystem::ODESystem,
pathYAML::String,
dirJulia::String;
jlFile::Bool=false,
customParameterValues::Union{Nothing, Dict}=nothing)
customParameterValues::Union{Nothing, Dict}=nothing,
writeToFile::Bool=true)

pODEProblemNames = string.(parameters(odeSystem))
modelStateNames = replace.(string.(states(odeSystem)), "(t)" => "")
Expand All @@ -22,7 +23,7 @@ function createCallbacksForTimeDepedentPiecewise(odeSystem::ODESystem,

# In case of no-callbacks the function for getting callbacks will be empty, likewise for the function
# which compute tstops (callback-times)
stringWriteCallbacks = "function getCallbacks_" * modelName * "()\n"
stringWriteCallbacks = "function getCallbacks_" * modelName * "(foo)\n"
stringWriteTstops = "\nfunction computeTstops(u::AbstractVector, p::AbstractVector)\n"

# In case we do not have any events
Expand Down Expand Up @@ -51,23 +52,25 @@ function createCallbacksForTimeDepedentPiecewise(odeSystem::ODESystem,
checkIfActivatedT0Names = ""
end

stringWriteTstops *= "\treturn" * createFuncionForTstops(SBMLDict, modelStateNames, pODEProblemNames, θ_indices) * "\n" * "end" * "\n"
stringWriteTstops *= "\treturn" * createFuncionForTstops(SBMLDict, modelStateNames, pODEProblemNames, θ_indices) * "\n" * "end"
end

# Check whether or not the trigger for a discrete callback depends on a parameter or not. If true then the time-span
# must be converted to dual when computing the gradient using ForwardDiff.
convertTspan = shouldConvertTspan(SBMLDict, odeSystem, θ_indices, jlFile)::Bool

stringWriteCallbacks *= "\treturn CallbackSet(" * callbackNames * "), Function[" * checkIfActivatedT0Names * "], " * string(convertTspan) * "\nend"
fileWrite = dirJulia * "/" * modelName * "_callbacks.jl"
if isfile(fileWrite)
rm(fileWrite)
pathSave = joinpath(dirJulia, modelName * "_callbacks.jl")
if isfile(pathSave)
rm(pathSave)
end
io = open(fileWrite, "w")
write(io, stringWriteCallbacks * "\n\n")
write(io, stringWriteTstops)

close(io)
if writeToFile == true
io = open(pathSave, "w")
write(io, stringWriteCallbacks * "\n\n")
write(io, stringWriteTstops)
close(io)
end
return stringWriteCallbacks, stringWriteTstops
end


Expand Down
Loading