Skip to content

Commit

Permalink
Merge pull request #704 from LCSB-BioCore/develop
Browse files Browse the repository at this point in the history
Develop → master merge for v1.4.2
  • Loading branch information
exaexa authored Nov 25, 2022
2 parents c79ab7f + 93d7988 commit 952fc04
Showing 13 changed files with 137 additions and 60 deletions.
52 changes: 41 additions & 11 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -3,18 +3,48 @@ on:
push:
branches:
- master
tags: '*'
- develop

jobs:
test:
name: run tests on github CI
runs-on: ubuntu-latest
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
version:
- '1.6' # Oldest supported version for COBREXA.jl
- '1' # This is always the latest stable release in the 1.X series
#- 'nightly'
os:
- ubuntu-latest
#- macOS-latest
#- windows-latest
arch:
- x64
steps:
- uses: actions/checkout@v2
- uses: addnab/docker-run-action@v3
- uses: actions/checkout@v3
- uses: julia-actions/setup-julia@v1
with:
username: cylon-x
password: ${{ secrets.gitlab_access_token }}
registry: ${{ secrets.docker_registry }}
image: ${{ secrets.docker_img }}
options: -v ${{ github.workspace }}:/pkg
run: julia --check-bounds=yes --inline=yes --project=/pkg -e "import Pkg; Pkg.test();"
version: ${{ matrix.version }}
arch: ${{ matrix.arch }}
- uses: actions/cache@v1
env:
cache-name: cache-artifacts
with:
path: ~/.julia/artifacts
key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }}
restore-keys: |
${{ runner.os }}-test-${{ env.cache-name }}-
${{ runner.os }}-test-
${{ runner.os }}-
- uses: julia-actions/julia-buildpkg@latest
- run: |
git config --global user.name Tester
git config --global user.email [email protected]
- uses: julia-actions/julia-runtest@latest
continue-on-error: ${{ matrix.version == 'nightly' }}
- uses: julia-actions/julia-processcoverage@v1
- uses: codecov/codecov-action@v1
with:
file: lcov.info
28 changes: 14 additions & 14 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -70,9 +70,9 @@ variables:
before_script:
- docker login -u $CI_USER_NAME -p $GITLAB_ACCESS_TOKEN $CI_REGISTRY

.global_julia17: &global_julia17
.global_julia18: &global_julia18
variables:
JULIA_VER: "v1.7.0"
JULIA_VER: "v1.8.3"

.global_julia16: &global_julia16
variables:
@@ -102,7 +102,7 @@ variables:
tags:
- mac
script:
- $ARTENOLIS_SOFT_PATH/julia/$JULIA_VER/Contents/Resources/julia/bin/julia --inline=yes --check-bounds=yes --color=yes --project=@. -e 'import Pkg; Pkg.test(; coverage = true)'
- $ARTENOLIS_SOFT_PATH_MAC/julia/$JULIA_VER/Contents/Resources/julia/bin/julia --inline=yes --check-bounds=yes --color=yes --project=@. -e 'import Pkg; Pkg.test(; coverage = true)'

.global_build_apptainer: &global_build_apptainer
image:
@@ -119,7 +119,7 @@ variables:
# any available docker and current julia
#

docker:julia1.7:
docker:julia1.8:
stage: test
image: $CI_REGISTRY/r3/docker/julia-custom
script:
@@ -133,12 +133,12 @@ docker:julia1.7:
# built & deployed
#

linux:julia1.7:
linux:julia1.8:
stage: test
tags:
- slave01
<<: *global_trigger_full_tests
<<: *global_julia17
<<: *global_julia18
<<: *global_env_linux

linux:julia1.6:
@@ -153,22 +153,22 @@ linux:julia1.6:
# Additional platform&environment compatibility tests
#

windows8:julia1.7:
windows8:julia1.8:
stage: test-compat
<<: *global_trigger_compat_tests
<<: *global_julia17
<<: *global_julia18
<<: *global_env_win8

windows10:julia1.7:
windows10:julia1.8:
stage: test-compat
<<: *global_trigger_compat_tests
<<: *global_julia17
<<: *global_julia18
<<: *global_env_win10

mac:julia1.7:
mac:julia1.8:
stage: test-compat
<<: *global_trigger_compat_tests
<<: *global_julia17
<<: *global_julia18
<<: *global_env_mac

windows8:julia1.6:
@@ -271,12 +271,12 @@ docker-release:
- julia --project=@. -e 'import Pkg; Pkg.instantiate();'
- julia --project=@. --color=yes test/doctests.jl

doc-tests-pr:julia1.7:
doc-tests-pr:julia1.8:
stage: documentation
<<: *global_doctests
<<: *global_trigger_pull_request

doc-tests:julia1.7:
doc-tests:julia1.8:
stage: test
<<: *global_doctests
<<: *global_trigger_full_tests
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "COBREXA"
uuid = "babc4406-5200-4a30-9033-bf5ae714c842"
authors = ["The developers of COBREXA.jl"]
version = "1.4.1"
version = "1.4.2"

[deps]
Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b"
1 change: 1 addition & 0 deletions src/base/constants.jl
Original file line number Diff line number Diff line change
@@ -27,6 +27,7 @@ const _constants = (
metformulas = ["metFormula", "metFormulas"],
metcharges = ["metCharge", "metCharges"],
metcompartments = ["metCompartment", "metCompartments", "metComp", "metComps"],
metcomptables = ["comps", "compNames"],
rxnnames = ["rxnNames"],
metnames = ["metNames"],
),
17 changes: 13 additions & 4 deletions src/base/types/MATModel.jl
Original file line number Diff line number Diff line change
@@ -168,10 +168,19 @@ $(TYPEDSIGNATURES)
Extract metabolite compartment from `metCompartment` or `metCompartments`.
"""
metabolite_compartment(m::MATModel, mid::String) = _maybemap(
x -> x[findfirst(==(mid), metabolites(m))],
gets(m.mat, nothing, _constants.keynames.metcompartments),
)
function metabolite_compartment(m::MATModel, mid::String)
res = _maybemap(
x -> x[findfirst(==(mid), metabolites(m))],
gets(m.mat, nothing, _constants.keynames.metcompartments),
)
# if the metabolite is an integer or a (very integerish) float, it is an
# index to a table of metabolite names (such as in the yeast GEM)
typeof(res) <: Real || return res
return _maybemap(
table -> table[Int(res)],
gets(m.mat, nothing, _constants.keynames.metcomptables),
)
end

"""
$(TYPEDSIGNATURES)
10 changes: 5 additions & 5 deletions src/base/types/SBMLModel.jl
Original file line number Diff line number Diff line change
@@ -62,11 +62,11 @@ function bounds(model::SBMLModel)::Tuple{Vector{Float64},Vector{Float64}}
getvalue = (val, _)::Tuple -> val
getunit = (_, unit)::Tuple -> unit

allunits = unique([getunit.(lbu) getunit.(ubu)])
length(allunits) == 1 || throw(
units_in_sbml = filter(!isempty, unique([getunit.(lbu) getunit.(ubu)]))
length(units_in_sbml) <= 1 || throw(
DomainError(
allunits,
"The SBML file uses multiple units; loading needs conversion",
units_in_sbml,
"The SBML file uses multiple units; loading would need conversion",
),
)

@@ -157,7 +157,7 @@ function _sbml_export_cvterms(annotations::Annotations)::Vector{SBML.CVTerm}
biological_qualifier = :is,
resource_uris = [
id == "RESOURCE_URI" ? val : "http://identifiers.org/$id/$val" for
(id, vals) = annotations if id != "sbo" for val in vals
(id, vals) in annotations if id != "sbo" for val in vals
],
),
]
2 changes: 1 addition & 1 deletion src/base/utils/gecko.jl
Original file line number Diff line number Diff line change
@@ -40,7 +40,7 @@ Compute the part of the coupling for [`GeckoModel`](@ref) that limits the
_gecko_reaction_coupling(model::GeckoModel) =
let tmp = [
(col.reaction_coupling_row, i, col.direction) for
(i, col) = enumerate(model.columns) if col.reaction_coupling_row != 0
(i, col) in enumerate(model.columns) if col.reaction_coupling_row != 0
]
sparse(
[row for (row, _, _) in tmp],
53 changes: 33 additions & 20 deletions src/io/io.jl
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@

"""
$(TYPEDSIGNATURES)
Generic function for loading models that chooses a specific loader function
from the `file_name` extension, or throws an error.
based on the `extension` argument (e.g., `".xml"` chooses loading of the SBML
model format), or throws an error. By default the extension from `file_name`
is used.
Currently, these model types are supported:
@@ -12,40 +13,48 @@ Currently, these model types are supported:
- MATLAB models (`*.mat`, loaded with [`load_mat_model`](@ref))
- HDF5 models (`*.h5`, loaded with [`load_h5_model`](@ref))
"""
function load_model(file_name::String)::MetabolicModel
if endswith(file_name, ".json")
function load_model(
file_name::String;
extension = last(splitext(file_name)),
)::MetabolicModel

if extension == ".json"
return load_json_model(file_name)
elseif endswith(file_name, ".xml")
elseif extension == ".xml"
return load_sbml_model(file_name)
elseif endswith(file_name, ".mat")
elseif extension == ".mat"
return load_mat_model(file_name)
elseif endswith(file_name, ".h5")
elseif extension == ".h5"
return load_h5_model(file_name)
else
throw(DomainError(file_name, "Unknown file extension"))
throw(DomainError(extension, "Unknown file extension"))
end
end


"""
$(TYPEDSIGNATURES)
Helper function tht loads the model using [`load_model`](@ref) and return it
Helper function that loads the model using [`load_model`](@ref) and returns it
converted to `type`.
# Example:
load_model(CoreModel, "mySBMLModel.xml")
"""
function load_model(type::Type{T}, file_name::String)::T where {T<:MetabolicModel}
convert(type, load_model(file_name))
function load_model(
type::Type{T},
file_name::String;
extension = last(splitext(file_name)),
)::T where {T<:MetabolicModel}
convert(type, load_model(file_name; extension))
end

"""
$(TYPEDSIGNATURES)
Generic function for saving models that chooses a specific writer function
from the `file_name` extension, or throws an error.
Generic function for saving models that chooses a specific writer function from
the `extension` argument (such as `".xml"` for SBML format), or throws an
error. By default the extension from `file_name` is used.
Currently, these model types are supported:
@@ -54,16 +63,20 @@ Currently, these model types are supported:
- MATLAB models (`*.mat`, saved with [`save_mat_model`](@ref))
- HDF5 models (`*.h5`, saved with [`save_h5_model`](@ref))
"""
function save_model(model::MetabolicModel, file_name::String)
if endswith(file_name, ".json")
function save_model(
model::MetabolicModel,
file_name::String;
extension = last(splitext(file_name)),
)
if extension == ".json"
return save_json_model(model, file_name)
elseif endswith(file_name, ".xml")
elseif extension == ".xml"
return save_sbml_model(model, file_name)
elseif endswith(file_name, ".mat")
elseif extension == ".mat"
return save_mat_model(model, file_name)
elseif endswith(file_name, ".h5")
elseif extension == ".h5"
return save_h5_model(model, file_name)
else
throw(DomainError(file_name, "Unknown file extension"))
throw(DomainError(extension, "Unknown file extension"))
end
end
2 changes: 1 addition & 1 deletion src/reconstruction/CoreModel.jl
Original file line number Diff line number Diff line change
@@ -353,7 +353,7 @@ end
remove_reactions!(
model,
[
ridx for ridx in 1:n_reactions(model) if
ridx for ridx = 1:n_reactions(model) if
any(in.(findnz(model.S[:, ridx])[1], Ref(metabolite_idxs)))
],
)
10 changes: 10 additions & 0 deletions test/data_downloaded.jl
Original file line number Diff line number Diff line change
@@ -68,4 +68,14 @@ model_paths = Dict{String,String}(
df("Recon3D.json"),
"aba925f17547a42f9fdb4c1f685d89364cbf4979bbe7862e9f793af7169b26d5",
),
"yeast-GEM.mat" => download_data_file(
"https://github.com/SysBioChalmers/yeast-GEM/raw/v8.6.2/model/yeast-GEM.mat",
df("yeast-GEM.mat"),
"c2587e258501737e0141cd47e0f854a60a47faee2d4c6ad582a00e437676b181",
),
"yeast-GEM.xml" => download_data_file(
"https://github.com/SysBioChalmers/yeast-GEM/raw/v8.6.2/model/yeast-GEM.xml",
df("yeast-GEM.xml"),
"c728b09d849b744ec7640cbf15776d40fb2d9cbd0b76a840a8661b626c1bd4be",
),
)
6 changes: 3 additions & 3 deletions test/io/h5.jl
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@

@testset "HDF5 model SBML model" begin
model = load_model(CoreModel, model_paths["e_coli_core.xml"])
fn = "ecoli_test.h5"
h5m = save_model(model, fn)
fn = "ecoli_test.h5.noextension"
h5m = save_model(model, fn, extension = ".h5")
@test h5m isa HDF5Model
@test h5m.filename == fn
@test h5m.h5 == nothing #the file should not be open by default

h5 = load_model(fn)
h5 = load_model(fn, extension = ".h5")
precache!(h5)
@test !isnothing(h5.h5)

7 changes: 7 additions & 0 deletions test/io/mat.jl
Original file line number Diff line number Diff line change
@@ -13,3 +13,10 @@ end
@test wrote isa CoreModel
@test isequal(wrote, loaded)
end

@testset "Import yeast-GEM (mat)" begin
m = load_model(StandardModel, model_paths["yeast-GEM.mat"])
@test n_metabolites(m) == 2744
@test n_reactions(m) == 4063
@test n_genes(m) == 1160
end
7 changes: 7 additions & 0 deletions test/io/sbml.jl
Original file line number Diff line number Diff line change
@@ -24,3 +24,10 @@ end
wrote = convert(CoreModel, load_sbml_model(testpath))
@test isequal(model, wrote)
end

@testset "Import yeast-GEM (sbml)" begin
m = load_model(StandardModel, model_paths["yeast-GEM.xml"])
@test n_metabolites(m) == 2744
@test n_reactions(m) == 4063
@test n_genes(m) == 1160
end

2 comments on commit 952fc04

@exaexa
Copy link
Collaborator Author

@exaexa exaexa commented on 952fc04 Nov 25, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/72879

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v1.4.2 -m "<description of version>" 952fc04fda9cf0ff6f3ed2bf6e180f796a2c79ec
git push origin v1.4.2

Please sign in to comment.