diff --git a/src/data_driven_rate_equation_selection.jl b/src/data_driven_rate_equation_selection.jl index 3b15aec..d5b172d 100644 --- a/src/data_driven_rate_equation_selection.jl +++ b/src/data_driven_rate_equation_selection.jl @@ -87,6 +87,7 @@ function data_driven_rate_equation_selection( param_names, param_removal_code_names, metab_names, + practically_unidentifiable_params, num_alpha_params, max_zero_alpha, ) @@ -108,6 +109,7 @@ function data_driven_rate_equation_selection( param_names, param_removal_code_names, metab_names, + practically_unidentifiable_params, num_alpha_params, max_zero_alpha, ) @@ -127,6 +129,7 @@ function data_driven_rate_equation_selection( nt_param_removal_codes = forward_selection_next_param_removal_codes( nt_previous_param_removal_codes, metab_names, + practically_unidentifiable_params, num_alpha_params, max_zero_alpha, ) @@ -134,6 +137,7 @@ function data_driven_rate_equation_selection( nt_param_removal_codes = reverse_selection_next_param_removal_codes( nt_previous_param_removal_codes, metab_names, + practically_unidentifiable_params, num_alpha_params, max_zero_alpha, ) @@ -356,6 +360,7 @@ function calculate_all_parameter_removal_codes_w_num_params( param_names::Tuple{Symbol,Vararg{Symbol}}, param_removal_code_names::Tuple{Symbol,Vararg{Symbol}}, metab_names::Tuple{Symbol,Vararg{Symbol}}, + practically_unidentifiable_params::Tuple{Vararg{Symbol}}, num_alpha_params::Int, max_zero_alpha::Int, ) @@ -388,16 +393,17 @@ function calculate_all_parameter_removal_codes_w_num_params( metab_names, ) end - if isempty(nt_param_removal_codes) - filtered_nt_param_removal_codes = NamedTuple[] + if isempty(filtered_nt_param_removal_codes) + filtered_nt_param_removal_codes_max_alpha = NamedTuple[] else - filtered_nt_param_removal_codes = + filtered_nt_param_removal_codes_max_alpha = filter_param_removal_codes_for_max_zero_alpha( nt_param_removal_codes, + practically_unidentifiable_params, max_zero_alpha, ) end - return filtered_nt_param_removal_codes + return filtered_nt_param_removal_codes_max_alpha end """ @@ -464,6 +470,7 @@ Calculate `nt_param_removal_codes` with `num_params` including non-zero term com function forward_selection_next_param_removal_codes( nt_previous_param_removal_codes::Vector{T} where {T<:NamedTuple}, metab_names::Tuple{Symbol,Vararg{Symbol}}, + practically_unidentifiable_params::Tuple{Vararg{Symbol}}, num_alpha_params::Int, max_zero_alpha::Int, ) @@ -505,16 +512,17 @@ function forward_selection_next_param_removal_codes( metab_names, ) end - if isempty(nt_param_removal_codes) - filtered_nt_param_removal_codes = NamedTuple[] + if isempty(filtered_nt_param_removal_codes) + filtered_nt_param_removal_codes_max_alpha = NamedTuple[] else - filtered_nt_param_removal_codes = + filtered_nt_param_removal_codes_max_alpha = filter_param_removal_codes_for_max_zero_alpha( nt_param_removal_codes, + practically_unidentifiable_params, max_zero_alpha, ) end - return filtered_nt_param_removal_codes + return filtered_nt_param_removal_codes_max_alpha end """ @@ -523,6 +531,7 @@ Use `nt_previous_param_removal_codes` to calculate `nt_next_param_removal_codes` function reverse_selection_next_param_removal_codes( nt_previous_param_removal_codes::Vector{T} where {T<:NamedTuple}, metab_names::Tuple{Symbol,Vararg{Symbol}}, + practically_unidentifiable_params::Tuple{Vararg{Symbol}}, num_alpha_params::Int, max_zero_alpha::Int, ) @@ -549,16 +558,17 @@ function reverse_selection_next_param_removal_codes( metab_names, ) end - if isempty(nt_param_removal_codes) - filtered_nt_param_removal_codes = NamedTuple[] + if isempty(filtered_nt_param_removal_codes) + filtered_nt_param_removal_codes_max_alpha = NamedTuple[] else - filtered_nt_param_removal_codes = + filtered_nt_param_removal_codes_max_alpha = filter_param_removal_codes_for_max_zero_alpha( nt_param_removal_codes, + practically_unidentifiable_params, max_zero_alpha, ) end - return filtered_nt_param_removal_codes + return filtered_nt_param_removal_codes_max_alpha end """Filter removal codes to ensure that if K_S1 = Inf then all K_S1_S2 and all other K containing S1 in qssa cannot be 2, which stands for (K_S1_S2)^2 = K_S1 * K_S2""" @@ -598,10 +608,18 @@ end """Filter removal codes to ensure that number of alpha that are 0 is max_zero_alpha""" function filter_param_removal_codes_for_max_zero_alpha( nt_param_removal_codes, + practically_unidentifiable_params::Tuple{Vararg{Symbol}}, max_zero_alpha::Int, ) - alpha_keys = - [key for key in keys(nt_param_removal_codes[1]) if occursin("alpha", string(key))] + practically_unidentifiable_alphas = [ + param for + param in practically_unidentifiable_params if occursin("alpha", string(param)) + ] + alpha_keys = [ + key for key in keys(nt_param_removal_codes[1]) if + occursin("alpha", string(key)) && key ∉ practically_unidentifiable_alphas + ] + if isempty(alpha_keys) filtered_nt_param_removal_codes = nt_param_removal_codes else diff --git a/test/tests_for_optimal_rate_eq_selection.jl b/test/tests_for_optimal_rate_eq_selection.jl index 424037f..058f61a 100644 --- a/test/tests_for_optimal_rate_eq_selection.jl +++ b/test/tests_for_optimal_rate_eq_selection.jl @@ -30,6 +30,7 @@ param_removal_code_names = ( !contains(string(param_name), "_i") && param_name != :Vmax && param_name != :L ]..., ) +practically_unidentifiable_params = () all_param_removal_codes = DataDrivenEnzymeRateEqs.calculate_all_parameter_removal_codes(param_names, ()) param_subset_codes_with_num_params = [ @@ -47,6 +48,7 @@ nt_funct_output_param_subset_codes = DataDrivenEnzymeRateEqs.forward_selection_next_param_removal_codes( nt_previous_param_removal_codes, metab_names, + practically_unidentifiable_params, n_alphas, max_zero_alpha, ) @@ -113,6 +115,7 @@ param_removal_code_names = ( !contains(string(param_name), "_i") && param_name != :Vmax && param_name != :L ]..., ) +practically_unidentifiable_params = () all_param_removal_codes = DataDrivenEnzymeRateEqs.calculate_all_parameter_removal_codes(param_names, ()) param_subset_codes_with_num_params = [ @@ -128,6 +131,7 @@ nt_funct_output_param_subset_codes = DataDrivenEnzymeRateEqs.reverse_selection_next_param_removal_codes( nt_previous_param_removal_codes, metab_names, + practically_unidentifiable_params, n_alphas, max_zero_alpha, ) @@ -180,6 +184,7 @@ param_names = ( [Symbol(:K_i, "_Metabolite$(i)") for i = 1:num_metabolites]..., [Symbol(:alpha, "_$(i)") for i = 1:n_alphas]..., ) +practically_unidentifiable_params = () param_removal_code_names = ( [ Symbol(replace(string(param_name), "_a_" => "_allo_")) for @@ -200,6 +205,7 @@ nt_param_subset_codes_w_num_params = param_names, param_removal_code_names, metab_names, + practically_unidentifiable_params, n_alphas, max_zero_alpha, ) @@ -270,10 +276,12 @@ correct_answer = [ @test filtered_nt == correct_answer #test filter_param_removal_codes_for_max_zero_alpha +#TODO: add a test with practically_unidentifiable_alphas num_alpha_params = rand(5:10) num_non_alpha_params = rand(5:10) max_zero_alpha = rand(1:3) param_names = ([Symbol("param$(i)") for i = 1:num_non_alpha_params]..., [Symbol("alpha$(i)") for i = 1:num_alpha_params]...) +param_names[end-num_alpha_params+1] nt_param_removal_codes = [ NamedTuple{(param_names)}(combo) for combo in Iterators.product([[0, 1] for _ in param_names]...) @@ -281,10 +289,15 @@ nt_param_removal_codes = [ filtered_nt = DataDrivenEnzymeRateEqs.filter_param_removal_codes_for_max_zero_alpha( nt_param_removal_codes, + practically_unidentifiable_params, max_zero_alpha, ) -sum_alpha = [sum(values(nt)[end-num_alpha_params:end]) for nt in filtered_nt] +sum_alpha = [sum(values(nt)[end-num_alpha_params+1:end]) for nt in filtered_nt] @test all(num_alpha_params .- sum_alpha .<= max_zero_alpha) +@test any(sum_alpha .== num_alpha_params-max_zero_alpha) +@test all(sum_alpha .!= num_alpha_params-max_zero_alpha-1) +@test any(sum_alpha .== num_alpha_params) +@test all(sum_alpha .!= num_alpha_params+1) #Load and process data LDH_data_for_fit = CSV.read(joinpath(@__DIR__, "Data_for_tests/LDH_data.csv"), DataFrame)