From 0012e6591e2d95921d99cd11f8f1f11468d64b3d Mon Sep 17 00:00:00 2001 From: Mirek Kratochvil <exa.exa@gmail.com> Date: Wed, 26 May 2021 15:41:39 +0200 Subject: [PATCH] FVA warmup --- src/analysis/sampling/warmup.jl | 71 ++++++++++++++++++++++---------- test/analysis/sampling/warmup.jl | 33 ++++----------- 2 files changed, 57 insertions(+), 47 deletions(-) diff --git a/src/analysis/sampling/warmup.jl b/src/analysis/sampling/warmup.jl index c4ae827e3..b75a42fe9 100644 --- a/src/analysis/sampling/warmup.jl +++ b/src/analysis/sampling/warmup.jl @@ -7,28 +7,53 @@ workers = [myid()], ) -Generates warmup points for samplers by minimizing and maximizing random -reactions. Very similar to -[`flux_variability_analysis`](@ref). +Generates FVA-like warmup points for samplers, by selecting random points by +minimizing and maximizing reactions. Can not return more than 2 times the +number of reactions in the model. """ -function warmup_from_variability( - n_points::Int, - model::MetabolicModel, - optimizer; - kwargs... -) +function warmup_from_variability(n_points::Int, model::MetabolicModel, optimizer; kwargs...) + nr = n_reactions(model) + + n_points > 2 * nr && throw( + DomainError( + n_points, + "Variability method can not generate more than $(2*nr) points from this model", + ), + ) - + sample = shuffle(vcat(1:nr, -(1:nr)))[begin:n_points] + warmup_from_variability( + -filter(x -> x < 0, sample), + filter(x -> x > 0, sample), + model, + optimizer; + kwargs..., + ) end +""" + warmup_from_variability( + min_reactions::Vector{Int}, + max_reactions::Vector{Int}, + model::MetabolicModel, + optimizer; + modifications=[], + workers::Vector{Int}=[myid()] + )::Matrix{Float64} + +Generate FVA-like warmup points for samplers, by minimizing and maximizing the +specified reactions. The result is returned as a matrix, each point occupies as +single column in the result. +""" function warmup_from_variability( min_reactions::Vector{Int}, max_reactions::Vector{Int}, model::MetabolicModel, optimizer; - modifications=[], - workers::Vector{Int}=[myid()] -)::Tuple{Matrix{Float64}, AbstractVector{Float64}, AbstractVector{Float64}} + modifications = [], + workers::Vector{Int} = [myid()], +)::Matrix{Float64} + # create optimization problem at workers, apply modifications save_model = :( begin @@ -43,18 +68,20 @@ function warmup_from_variability( map(fetch, save_at.(workers, :cobrexa_sampling_warmup_optmodel, Ref(save_model))) - fluxes = dpmap( - rid -> :($COBREXA._FVA_optimize_reaction( - cobrexa_sampling_warmup_optmodel, - $rid, - optmodel -> value.(optmodel[:x]), - )), - CachingPool(workers), - vcat(-min_reactions, max_reactions), + fluxes = hcat( + dpmap( + rid -> :($COBREXA._FVA_optimize_reaction( + cobrexa_sampling_warmup_optmodel, + $rid, + optmodel -> $COBREXA.JuMP.value.(optmodel[:x]), + )), + CachingPool(workers), + vcat(-min_reactions, max_reactions), + )..., ) # free the data on workers map(fetch, remove_from.(workers, :cobrexa_sampling_warmup_optmodel)) - return hcat(fluxes...) + return fluxes end diff --git a/test/analysis/sampling/warmup.jl b/test/analysis/sampling/warmup.jl index 2b6291de2..0c505f6a7 100644 --- a/test/analysis/sampling/warmup.jl +++ b/test/analysis/sampling/warmup.jl @@ -6,33 +6,16 @@ ) model = load_model(StandardModel, model_path) - # Serial test - ws, lbs, ubs = warmup( + pts = warmup_from_variability( + 100, model, Tulip.Optimizer; - modifications = [change_constraint("EX_glc__D_e", -4, 4)], - warmup_points = collect(1:n_reactions(model)), - workerids = W, + modifications = [change_constraint("EX_glc__D_e", -2, 2)], + workers = W, ) - ind = first(indexin(["EX_glc__D_e"], reactions(model))) - @test size(ws) == (95, 2) - @test size(ws[1, 1]) == (95,) - @test lbs[ind] ≈ -4 - @test ubs[ind] ≈ 4 - - # Parallel test - wsparallel, lbsparallel, ubsparallel = warmup( - model, - Tulip.Optimizer; - modifications = [change_constraint("EX_glc__D_e", -4, 4)], - warmup_points = collect(1:n_reactions(model)), - workerids = W, - ) - - ind = first(indexin(["EX_glc__D_e"], reactions(model))) - @test size(wsparallel) == (95, 2) - @test size(wsparallel[1, 1]) == (95,) - @test lbsparallel[ind] ≈ -4 - @test ubsparallel[ind] ≈ 4 + idx = first(indexin(["EX_glc__D_e"], reactions(model))) + @test size(pts) == (95, 100) + @test all(pts[idx, :] .>= -2) + @test all(pts[idx, :] .<= 2) end -- GitLab