Commit f2b6185e authored by Miroslav Kratochvil's avatar Miroslav Kratochvil
Browse files

clean up all trailing whitespace

parent bdf6d98a
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
[docs-img]:https://img.shields.io/badge/docs-latest-blue.svg [docs-img]:https://img.shields.io/badge/docs-latest-blue.svg
[docs-url]: https://stelmo.github.io/CobraTools.jl/dev [docs-url]: https://stelmo.github.io/CobraTools.jl/dev
[ci-img]: https://github.com/stelmo/CobraTools.jl/actions/workflows/ci.yml/badge.svg?branch=master&event=push [ci-img]: https://github.com/stelmo/CobraTools.jl/actions/workflows/ci.yml/badge.svg?branch=master&event=push
[ci-url]: https://github.com/stelmo/CobraTools.jl/actions/workflows/ci.yml [ci-url]: https://github.com/stelmo/CobraTools.jl/actions/workflows/ci.yml
...@@ -40,9 +40,9 @@ using JuMP ...@@ -40,9 +40,9 @@ using JuMP
using Tulip # pick any solver supported by JuMP using Tulip # pick any solver supported by JuMP
# Import E. coli models (models have pretty printing) # Import E. coli models (models have pretty printing)
model_1 = read_model("iJO1366.json") model_1 = read_model("iJO1366.json")
model_2 = read_model("iJO1366.json") model_2 = read_model("iJO1366.json")
model_3 = read_model("iJO1366.json") model_3 = read_model("iJO1366.json")
# Build an exascale model # Build an exascale model
exascale_model = join(model_1, model_2, model_3,...) exascale_model = join(model_1, model_2, model_3,...)
......
...@@ -18,7 +18,7 @@ flux_balance_analysis(model::M, optimizer) where {M<:MetabolicModel} = ...@@ -18,7 +18,7 @@ flux_balance_analysis(model::M, optimizer) where {M<:MetabolicModel} =
Run flux balance analysis (FBA) on the `model` optionally specifying `objective_rxn(s)` and their `weights` (empty `weights` mean equal weighting per reaction). Run flux balance analysis (FBA) on the `model` optionally specifying `objective_rxn(s)` and their `weights` (empty `weights` mean equal weighting per reaction).
Optionally also specify any additional flux constraints with `constraints`, a dictionary mapping reaction `id`s to tuples of (lb, ub) flux constraints. Optionally also specify any additional flux constraints with `constraints`, a dictionary mapping reaction `id`s to tuples of (lb, ub) flux constraints.
Note, the `optimizer` must be set to perform the analysis, any JuMP solver will work. Note, the `optimizer` must be set to perform the analysis, any JuMP solver will work.
The `solver_attributes` can also be specified in the form of a dictionary where each (key, value) pair will be passed to `set_optimizer_attribute(cbmodel, key, value)`. The `solver_attributes` can also be specified in the form of a dictionary where each (key, value) pair will be passed to `set_optimizer_attribute(cbmodel, key, value)`.
This function builds the optimization problem from the model, and hence uses the constraints implied by the model object. This function builds the optimization problem from the model, and hence uses the constraints implied by the model object.
Returns a dictionary of reaction `id`s mapped to fluxes if solved successfully, otherwise an empty dictionary. Returns a dictionary of reaction `id`s mapped to fluxes if solved successfully, otherwise an empty dictionary.
......
""" """
map_fluxes(v, model::CobraModel) map_fluxes(v, model::CobraModel)
Map fluxes from an optimization problem (`v`) to rxns in a model. Map fluxes from an optimization problem (`v`) to rxns in a model.
`v` can be a JuMP object (fluxes) or an array of Float64 fluxes. `v` can be a JuMP object (fluxes) or an array of Float64 fluxes.
Assumes they are in order of `model.reactions`, which they should be since the optimization problem is constructed from the model. Assumes they are in order of `model.reactions`, which they should be since the optimization problem is constructed from the model.
""" """
...@@ -24,7 +24,7 @@ end ...@@ -24,7 +24,7 @@ end
""" """
atom_exchange(flux_dict::Dict{String, Float64}, model::CobraModel) atom_exchange(flux_dict::Dict{String, Float64}, model::CobraModel)
Return a dictionary mapping the flux of atoms across the boundary of the model given `flux_dict` of reactions in `model`. Return a dictionary mapping the flux of atoms across the boundary of the model given `flux_dict` of reactions in `model`.
Here `flux_dict` is a mapping of reaction `id`s to fluxes, e.g. from FBA. Here `flux_dict` is a mapping of reaction `id`s to fluxes, e.g. from FBA.
""" """
function atom_exchange(flux_dict::Dict{String,Float64}, model::CobraModel) function atom_exchange(flux_dict::Dict{String,Float64}, model::CobraModel)
...@@ -45,7 +45,7 @@ end ...@@ -45,7 +45,7 @@ end
""" """
get_exchanges(rxndict::Dict{String, Float64}; top_n=8, ignorebound=1000.0, verbose=true) get_exchanges(rxndict::Dict{String, Float64}; top_n=8, ignorebound=1000.0, verbose=true)
Display the top_n producing and consuming exchange fluxes. Display the top_n producing and consuming exchange fluxes.
Set top_n to a large number to get all the consuming/producing fluxes. Set top_n to a large number to get all the consuming/producing fluxes.
Ignores infinite (problem upper/lower bound) fluxes (set with ignorebound). Ignores infinite (problem upper/lower bound) fluxes (set with ignorebound).
When `verbose` is false, the output is not printed out. When `verbose` is false, the output is not printed out.
......
...@@ -116,7 +116,7 @@ Run flux variability analysis (FVA) on the `model` with `objective_rxn(s)` and o ...@@ -116,7 +116,7 @@ Run flux variability analysis (FVA) on the `model` with `objective_rxn(s)` and o
It runs fba on the model once to determine the optimum of the objective. It runs fba on the model once to determine the optimum of the objective.
Optionally also specify any additional flux constraints with `constraints`, a dictionary mapping reaction `id`s to tuples of (ub, lb) flux constraints. Optionally also specify any additional flux constraints with `constraints`, a dictionary mapping reaction `id`s to tuples of (ub, lb) flux constraints.
The model is then constrained to produce objective flux bounded by `optimum_bound` from below (set to slightly less than 1.0 for stability) and each flux in the model sequentially minimized and maximized. The model is then constrained to produce objective flux bounded by `optimum_bound` from below (set to slightly less than 1.0 for stability) and each flux in the model sequentially minimized and maximized.
Note, the `optimizer` must be set to perform the analysis, any JuMP solver will work. Note, the `optimizer` must be set to perform the analysis, any JuMP solver will work.
The `solver_attributes` can also be specified in the form of a dictionary where each (key, value) pair will be passed to `set_optimizer_attribute(cbmodel, key, value)`. The `solver_attributes` can also be specified in the form of a dictionary where each (key, value) pair will be passed to `set_optimizer_attribute(cbmodel, key, value)`.
This function builds the optimization problem from the model, and hence uses the constraints implied by the model object. This function builds the optimization problem from the model, and hence uses the constraints implied by the model object.
Returns two dictionaries (`fva_max` and `fva_min`) that each reaction `id`s to dictionaries of the resultant flux distributions (if solved successfully) when that `id` is optimized. Returns two dictionaries (`fva_max` and `fva_min`) that each reaction `id`s to dictionaries of the resultant flux distributions (if solved successfully) when that `id` is optimized.
......
...@@ -117,7 +117,7 @@ function pfba( ...@@ -117,7 +117,7 @@ function pfba(
for lbconval in [0.999999, 0.99999, 0.9999, 0.999, 0.99] # relax bound for stability for lbconval in [0.999999, 0.99999, 0.9999, 0.999, 0.99] # relax bound for stability
if termination_status(cbm) == MOI.OPTIMAL || if termination_status(cbm) == MOI.OPTIMAL ||
termination_status(cbm) == MOI.LOCALLY_SOLVED # try to relax bound if failed optimization termination_status(cbm) == MOI.LOCALLY_SOLVED # try to relax bound if failed optimization
break break
else else
JuMP.delete(cbm, pfbacon) JuMP.delete(cbm, pfbacon)
......
...@@ -7,17 +7,17 @@ The model format is inferred from the `file_location` extension. ...@@ -7,17 +7,17 @@ The model format is inferred from the `file_location` extension.
Note, some meta-information may be lost when importing a model. Importantly, only information regarding the Note, some meta-information may be lost when importing a model. Importantly, only information regarding the
reactions, metabolites and genes are imported. Currently reading JSON models captures the most meta-information reactions, metabolites and genes are imported. Currently reading JSON models captures the most meta-information
regarding reactions, metabolites and genes (e.g. the notes and annotation fields). regarding reactions, metabolites and genes (e.g. the notes and annotation fields).
When importing Matlab models some annotation and notes may not be imported because of non-standard field names used by some models. When importing Matlab models some annotation and notes may not be imported because of non-standard field names used by some models.
Gene reaction rules are successfully imported only if they adhere to this format: `"(YIL010W and YLR043C) or (YIL010W and YGR209C)"`, Gene reaction rules are successfully imported only if they adhere to this format: `"(YIL010W and YLR043C) or (YIL010W and YGR209C)"`,
where `or` can be interchanged with `OR, |, ||` and `and` can be interchanged with `AND, &, &&`. where `or` can be interchanged with `OR, |, ||` and `and` can be interchanged with `AND, &, &&`.
Other gene reaction rules formats are not supported yet, but file an issue if your format is standard and needs to be included. Other gene reaction rules formats are not supported yet, but file an issue if your format is standard and needs to be included.
However, in all cases the basic information needed to perform constraint based analysis should be imported successfully, However, in all cases the basic information needed to perform constraint based analysis should be imported successfully,
e.g. stoichiometrix matrix, constraints etc.. e.g. stoichiometrix matrix, constraints etc..
Advanced tools that require, e.g. metabolite formulas, gene reaction rules, and KEGG or BIGG IDs, will not function if these are improperly imported. Advanced tools that require, e.g. metabolite formulas, gene reaction rules, and KEGG or BIGG IDs, will not function if these are improperly imported.
Always inspect the imported model before running analysis (garbage in -> garbage out). Always inspect the imported model before running analysis (garbage in -> garbage out).
""" """
function read_model(file_location::String) function read_model(file_location::String)
if endswith(file_location, ".json") if endswith(file_location, ".json")
...@@ -73,7 +73,7 @@ end ...@@ -73,7 +73,7 @@ end
""" """
parsegrr(string_rule, genes::Array{Gene, 1}) parsegrr(string_rule, genes::Array{Gene, 1})
Parse a gene reaction rule string `string_rule` into a nested `gene` array `Array{Array{Gene, 1}, 1}`. Parse a gene reaction rule string `string_rule` into a nested `gene` array `Array{Array{Gene, 1}, 1}`.
Format: (YIL010W and YLR043C) or (YIL010W and YGR209C) where `or` can also be `OR, |, ||` and where `and` can also be `AND, &, &&`. Format: (YIL010W and YLR043C) or (YIL010W and YGR209C) where `or` can also be `OR, |, ||` and where `and` can also be `AND, &, &&`.
""" """
......
...@@ -129,7 +129,7 @@ end ...@@ -129,7 +129,7 @@ end
Inspect metabolites and genes of `model` relative to the reactions of `model`. Inspect metabolites and genes of `model` relative to the reactions of `model`.
Remove genes or metabolites that are not used in the reactions. Remove genes or metabolites that are not used in the reactions.
Add genes or metabolites that are not present in `model.genes` or `model.metabolites` but are used in `model.reactions`. Add genes or metabolites that are not present in `model.genes` or `model.metabolites` but are used in `model.reactions`.
Everything is based on the `id` of metabolites and genes, thus is it possible for a metabolite or gene to be duplicated but using Everything is based on the `id` of metabolites and genes, thus is it possible for a metabolite or gene to be duplicated but using
a different `id`. Other functions are provided to help identify these cases. a different `id`. Other functions are provided to help identify these cases.
......
""" """
get_warmup_points(cbmodel, v, mb, lbs, ubs; random_objective=false, numstop=1e10) get_warmup_points(cbmodel, v, mb, lbs, ubs; random_objective=false, numstop=1e10)
Generate warmup points for all the reactions on the model that Generate warmup points for all the reactions on the model that
are not fixed. Assumes you feed in a JuMP model that is already are not fixed. Assumes you feed in a JuMP model that is already
constrained i.e. the constrains are already applied into cbmodel. constrained i.e. the constrains are already applied into cbmodel.
Note, extra constraints applied to ubs and lbs will have no effect. Note, extra constraints applied to ubs and lbs will have no effect.
...@@ -77,14 +77,14 @@ end ...@@ -77,14 +77,14 @@ end
""" """
hit_and_run(N::Int64, model::CobraModel, optimizer; constraints=Dict{String, Tuple{Float64,Float64}}(), keepevery=100, samplesize=1000, solver_attributes=Dict{Any, Any}(), random_objective=false) hit_and_run(N::Int64, model::CobraModel, optimizer; constraints=Dict{String, Tuple{Float64,Float64}}(), keepevery=100, samplesize=1000, solver_attributes=Dict{Any, Any}(), random_objective=false)
Perform basic hit and run sampling for `N` iterations using `model` with `optimizer` from `JuMP`. Perform basic hit and run sampling for `N` iterations using `model` with `optimizer` from `JuMP`.
Additional constraints supplied by `constraints` as a dictionary of reaction `id`s mapped to a tuple of `(lb, ub)` of fluxes. Additional constraints supplied by `constraints` as a dictionary of reaction `id`s mapped to a tuple of `(lb, ub)` of fluxes.
Every `keepevery` iteration is logged as a sample, where the sample size matrix has `samplesize` columns. Every `keepevery` iteration is logged as a sample, where the sample size matrix has `samplesize` columns.
Solver specific settings can be set using `solver_attributes`. Solver specific settings can be set using `solver_attributes`.
Warm up points are generated in a flux variability sense, unless `random_objective` is true, in which case a randomly weighted objective is used 2*number of reactions to define the warmup points. Warm up points are generated in a flux variability sense, unless `random_objective` is true, in which case a randomly weighted objective is used 2*number of reactions to define the warmup points.
Note that N needs to be >> samplesize. Note that N needs to be >> samplesize.
Sample size is the size of the samples kept in memory. Sample size is the size of the samples kept in memory.
The larger samplesize is the better the approximation becomes, but the more memory the sampler requires. The larger samplesize is the better the approximation becomes, but the more memory the sampler requires.
See also: [`achr`](@ref) See also: [`achr`](@ref)
...@@ -126,13 +126,13 @@ function hit_and_run( ...@@ -126,13 +126,13 @@ function hit_and_run(
current_point = zeros(size(wpoints, 1)) current_point = zeros(size(wpoints, 1))
current_point .= wpoints[:, rand(1:nwpts)] # pick random initial point current_point .= wpoints[:, rand(1:nwpts)] # pick random initial point
δdirtol = 1e-6 # too small directions get ignored ≈ 0 (solver precision issue) δdirtol = 1e-6 # too small directions get ignored ≈ 0 (solver precision issue)
sample_num = 0 sample_num = 0
samplelength = 0 samplelength = 0
updatesamplesizelength = true updatesamplesizelength = true
for n = 1:N for n = 1:N
# direction = random point - current point # direction = random point - current point
if updatesamplesizelength if updatesamplesizelength
direction_point = (@view wpoints[:, rand(1:nwpts)]) - (@view current_point[:]) # use warmup points to find direction in warmup phase direction_point = (@view wpoints[:, rand(1:nwpts)]) - (@view current_point[:]) # use warmup points to find direction in warmup phase
else else
...@@ -157,7 +157,7 @@ function hit_and_run( ...@@ -157,7 +157,7 @@ function hit_and_run(
upper = 1e10 upper = 1e10
end end
lower > λmin && (λmin = lower) # max min step size that satisfies all bounds lower > λmin && (λmin = lower) # max min step size that satisfies all bounds
upper < λmax && (λmax = upper) # min max step size that satisfies all bounds upper < λmax && (λmax = upper) # min max step size that satisfies all bounds
end end
if λmax <= λmin || λmin == -1e10 || λmax == 1e10 # this sometimes can happen if λmax <= λmin || λmin == -1e10 || λmax == 1e10 # this sometimes can happen
...@@ -260,12 +260,12 @@ function achr( ...@@ -260,12 +260,12 @@ function achr(
shat = mean(wpoints, dims = 2)[:] # mean point shat = mean(wpoints, dims = 2)[:] # mean point
δdirtol = 1e-6 # too small directions get ignored ≈ 0 (solver precision issue) δdirtol = 1e-6 # too small directions get ignored ≈ 0 (solver precision issue)
sample_num = 0 sample_num = 0
samplelength = 0 samplelength = 0
updatesamplesizelength = true updatesamplesizelength = true
for n = 1:N for n = 1:N
if updatesamplesizelength # switch to samples if updatesamplesizelength # switch to samples
direction_point = (@view wpoints[:, rand(1:nwpts)]) - (@view current_point[:]) # use warmup points to find direction in warmup phase direction_point = (@view wpoints[:, rand(1:nwpts)]) - (@view current_point[:]) # use warmup points to find direction in warmup phase
else else
direction_point = (@view samples[:, rand(1:(samplelength))]) - (@view shat[:]) # after warmup phase, only find directions in sampled space direction_point = (@view samples[:, rand(1:(samplelength))]) - (@view shat[:]) # after warmup phase, only find directions in sampled space
...@@ -287,7 +287,7 @@ function achr( ...@@ -287,7 +287,7 @@ function achr(
upper = 1e10 upper = 1e10
end end
lower > λmin && (λmin = lower) # max min step size that satisfies all bounds lower > λmin && (λmin = lower) # max min step size that satisfies all bounds
upper < λmax && (λmax = upper) # min max step size that satisfies all bounds upper < λmax && (λmax = upper) # min max step size that satisfies all bounds
end end
if λmax <= λmin || λmin == -1e10 || λmax == 1e10 # this sometimes can happen if λmax <= λmin || λmin == -1e10 || λmax == 1e10 # this sometimes can happen
......
...@@ -7,7 +7,7 @@ id :: String ...@@ -7,7 +7,7 @@ id :: String
name :: String name :: String
notes :: Dict{String, Array{String, 1}} notes :: Dict{String, Array{String, 1}}
annotation :: Dict{String, Union{Array{String, 1}, String}} annotation :: Dict{String, Union{Array{String, 1}, String}}
```` ````
""" """
mutable struct Gene mutable struct Gene
id::String id::String
...@@ -74,7 +74,7 @@ end ...@@ -74,7 +74,7 @@ end
""" """
getindex(genes::Array{Gene, 1}, gene::Gene) getindex(genes::Array{Gene, 1}, gene::Gene)
Get the index of a `gene` in an array of `genes` based on `id` field. Get the index of a `gene` in an array of `genes` based on `id` field.
Return -1 if no matches found. Return -1 if no matches found.
Typically used `index = genes[gene]`. Typically used `index = genes[gene]`.
...@@ -92,7 +92,7 @@ end ...@@ -92,7 +92,7 @@ end
findfirst(genes::Array{Gene, 1}, geneid::String) findfirst(genes::Array{Gene, 1}, geneid::String)
Return the gene with `geneid` in `genes` or else `nothing`. Return the gene with `geneid` in `genes` or else `nothing`.
Based on matching `id` fields. Based on matching `id` fields.
Typically used: `gene = findfirst(model.genes, geneid)`. Typically used: `gene = findfirst(model.genes, geneid)`.
""" """
......
...@@ -83,11 +83,11 @@ end ...@@ -83,11 +83,11 @@ end
""" """
getindex(mets::Array{Metabolite, 1}, met::Metabolite) getindex(mets::Array{Metabolite, 1}, met::Metabolite)
Get the index of a `met` in an array of `mets`, based on `id` equality. Get the index of a `met` in an array of `mets`, based on `id` equality.
Return -1 if no matches found. Return -1 if no matches found.
This function overrides the `[]` notation from Base. This function overrides the `[]` notation from Base.
Typically used: `index = mets[met]` works. Typically used: `index = mets[met]` works.
""" """
function Base.getindex(mets::Array{Metabolite,1}, met::Metabolite) function Base.getindex(mets::Array{Metabolite,1}, met::Metabolite)
for i in eachindex(mets) for i in eachindex(mets)
...@@ -101,8 +101,8 @@ end ...@@ -101,8 +101,8 @@ end
""" """
findfirst(mets::Array{Metabolite, 1}, metid::String) findfirst(mets::Array{Metabolite, 1}, metid::String)
Return the metabolite in `mets` with `metid`, based in `id` field. Return the metabolite in `mets` with `metid`, based in `id` field.
If nothing matches, return `nothing`. If nothing matches, return `nothing`.
Typically used: `met = findfirst(model.mets, metid)`. Typically used: `met = findfirst(model.mets, metid)`.
""" """
......
...@@ -125,7 +125,7 @@ end ...@@ -125,7 +125,7 @@ end
Reaction(id::String, metabolites::Dict{Metabolite, Float64}, dir="bidir") Reaction(id::String, metabolites::Dict{Metabolite, Float64}, dir="bidir")
Assign the `id`, `metabolites` (and their associated stoichiometries), and the direcionality (`dir`) of a reaction to a `Reaction` struct. Assign the `id`, `metabolites` (and their associated stoichiometries), and the direcionality (`dir`) of a reaction to a `Reaction` struct.
Directionality is specified using `"for"` (forward), `"rev"` (reverse), or any other string for bidirectional reactions. Directionality is specified using `"for"` (forward), `"rev"` (reverse), or any other string for bidirectional reactions.
All other fields are left unassigned. All other fields are left unassigned.
See also: [`Reaction()`](@ref). See also: [`Reaction()`](@ref).
...@@ -164,7 +164,7 @@ end ...@@ -164,7 +164,7 @@ end
""" """
getindex(rxns::Array{Reaction, 1}, rxn::Reaction) getindex(rxns::Array{Reaction, 1}, rxn::Reaction)
Get the index of a reaction `rxn` in an array of reactions `rxns`, based in `id`. Get the index of a reaction `rxn` in an array of reactions `rxns`, based in `id`.
Return -1 if no matches found. Return -1 if no matches found.
Typically used, `index = rxns[rxn]`. Typically used, `index = rxns[rxn]`.
...@@ -197,9 +197,9 @@ end ...@@ -197,9 +197,9 @@ end
""" """
check_duplicate_reaction(rxns::Array{Reaction, 1}, rxn::Reaction) check_duplicate_reaction(rxns::Array{Reaction, 1}, rxn::Reaction)
Check if `rxn` already exists in `rxns` but has another id. Check if `rxn` already exists in `rxns` but has another id.
Looks through all the reaction equations of `rxns` and compares metabolite `id`s and their stoichiometric coefficients to those of `rxn`. Looks through all the reaction equations of `rxns` and compares metabolite `id`s and their stoichiometric coefficients to those of `rxn`.
If `rxn` has the same reaction equation as another reaction in `rxns`, the return true and the index of the first match. If `rxn` has the same reaction equation as another reaction in `rxns`, the return true and the index of the first match.
See also: [`is_mass_balanced`](@ref) See also: [`is_mass_balanced`](@ref)
""" """
......
...@@ -48,7 +48,7 @@ end ...@@ -48,7 +48,7 @@ end
""" """
getindex(model::CobraModel, rxn::Reaction) getindex(model::CobraModel, rxn::Reaction)
Get the index of `rxn` in `model`, based on reaction `id`. Get the index of `rxn` in `model`, based on reaction `id`.
Return -1 if not found. Return -1 if not found.
Typical usage: ind = model[rxn] Typical usage: ind = model[rxn]
...@@ -60,7 +60,7 @@ end ...@@ -60,7 +60,7 @@ end
""" """
getindex(model::CobraModel, met::Metabolite) getindex(model::CobraModel, met::Metabolite)
Get the index of `met` in `model`, based on metabolite `id`. Get the index of `met` in `model`, based on metabolite `id`.
Return -1 if not found. Return -1 if not found.
Typical usage: ind = model[met] Typical usage: ind = model[met]
...@@ -72,7 +72,7 @@ end ...@@ -72,7 +72,7 @@ end
""" """
getindex(model::CobraModel, gene::Gene) getindex(model::CobraModel, gene::Gene)
Get the index of `gene` in `model`, based on gene `id`. Get the index of `gene` in `model`, based on gene `id`.
Return -1 if not found. Return -1 if not found.
Typical usage: ind = model[gene] Typical usage: ind = model[gene]
......
...@@ -46,7 +46,7 @@ function model_comparison_test(model1, model2) ...@@ -46,7 +46,7 @@ function model_comparison_test(model1, model2)
end end
""" """
Test if model is the same after it was read in, saved, and then re-read. Test if model is the same after it was read in, saved, and then re-read.
""" """
function read_write_read_test(model, format) function read_write_read_test(model, format)
tmpfile = joinpath("data", "temp." * format) tmpfile = joinpath("data", "temp." * format)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment