Skip to content

Commit

Permalink
Migrate to pure julia (#59)
Browse files Browse the repository at this point in the history
* [WIP] update dependencies and remove pycall

* some cleaning and remove Sleipnir dependency

* making the tests pass locally

* code cleaning

* bump version

* update CI and Project.toml
  • Loading branch information
albangossard authored Jan 23, 2025
1 parent b13413f commit 2413919
Show file tree
Hide file tree
Showing 16 changed files with 76 additions and 151 deletions.
53 changes: 14 additions & 39 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,42 +22,14 @@ jobs:
fail-fast: false
matrix:
version:
- '1.10'
python: [3.9]
- '1.11'
os:
- ubuntu-latest
- macos-latest
arch:
- x64
steps:
- uses: actions/checkout@v2
- name: Set up Python 🐍 ${{ matrix.python }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python }}
- name: Create environment with micromamba 🐍🖤
uses: mamba-org/setup-micromamba@v1
with:
micromamba-version: '1.5.6-0'
environment-file: ./environment.yml
environment-name: oggm_env # it is recommendable to add both name and yml file.
init-shell: bash
cache-environment: true
# condarc-file: ./condarc.yml # If necessary, we can include .condarc to configure environment
- name: Test creation of environment with micromamba 🔧🐍🖤
run: |
which python
conda env export
shell: bash -el {0}
- name: Update certifi
run: |
pip install --upgrade certifi
shell: bash -el {0}
# - name: Test OGGM installation 🔧🌎
# run: pytest.oggm
# shell: bash -el {0}
- name: Set ENV Variables for PyCall.jl 🐍 📞
run: export PYTHON=/home/runner/micromamba/envs/oggm_env/bin/python
shell: bash -el {0}
- uses: julia-actions/setup-julia@v1
with:
version: ${{ matrix.version }}
Expand All @@ -69,15 +41,18 @@ jobs:
with:
cache-registries: "true"
cache-compiled: "true"
- uses: julia-actions/julia-buildpkg@v1
env:
PYTHON : /home/runner/micromamba/envs/oggm_env/bin/python
# The SSL certificate path can be readed from the action "Check Julia SSL certifications"
SSL_CERT_FILE: /etc/ssl/certs/ca-certificates.crt
- uses: julia-actions/julia-runtest@v1
env:
PYTHON : /home/runner/micromamba/envs/oggm_env/bin/python
SSL_CERT_FILE: /etc/ssl/certs/ca-certificates.crt
- name: Build Julia packages in Ubuntu
uses: julia-actions/julia-buildpkg@v1
if: matrix.os == 'ubuntu-latest'
- name: Build Julia packages in MacOS
uses: julia-actions/julia-buildpkg@v1
if: matrix.os == 'macos-latest'
- name: Run tests in Ubuntu
uses: julia-actions/julia-runtest@v1
if: matrix.os == 'ubuntu-latest'
- name: Run tests in MacOS
uses: julia-actions/julia-runtest@v1
if: matrix.os == 'macos-latest'
- uses: julia-actions/julia-processcoverage@v1
- uses: codecov/codecov-action@v3
with:
Expand Down
10 changes: 4 additions & 6 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "Huginn"
uuid = "9cb796e9-d0ea-421b-b37d-eb97bc1add55"
authors = ["Jordi Bolibar <[email protected]>", "Facundo Sapienza <[email protected]>"]
version = "0.6.0"
version = "0.7.0"

[deps]
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
Expand All @@ -17,7 +17,6 @@ Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
PlotThemes = "ccf2f8ad-2431-5c83-bf29-c5338b663b6a"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
ProgressMeter = "92933f4c-e287-5a05-a399-4b506db050ca"
PyCall = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0"
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
Revise = "295af30f-e4ad-537b-8983-00126c2a3abe"
Sleipnir = "f5e6c550-199f-11ee-3608-394420200519"
Expand All @@ -27,19 +26,18 @@ Tullio = "bc48ee85-29a4-5162-ae0b-a64e1601d4bc"
[compat]
BenchmarkTools = "1"
CairoMakie = "0.11, 0.12"
Infiltrator = "1"
Infiltrator = "1.8"
JLD2 = "0.4"
Muninn = "0.3"
Muninn = "0.4.0"
Optimization = "3"
OptimizationOptimJL = "0.3"
OrdinaryDiffEq = "6"
PlotThemes = "3"
Plots = "1"
ProgressMeter = "1"
PyCall = "1"
Reexport = "1"
Revise = "3"
Sleipnir = "0.6"
Sleipnir = "0.7.0"
Tullio = "0.3"
julia = "1.7"

Expand Down
23 changes: 0 additions & 23 deletions src/Huginn.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ using CairoMakie
import Pkg
using Distributed
using ProgressMeter
using PyCall

### ODINN.jl dependencies ###
using Reexport
Expand All @@ -30,28 +29,6 @@ cd(@__DIR__)
const global root_dir::String = dirname(Base.current_project())
const global root_plots::String = joinpath(root_dir, "plots")

# ##############################################
# ############ PYTHON LIBRARIES ##############
# ##############################################

# We either retrieve the reexported Python libraries from Sleipnir or we start from scratch
const netCDF4::PyObject = isdefined(Sleipnir, :netCDF4) ? Sleipnir.netCDF4 : PyNULL()
const cfg::PyObject = isdefined(Sleipnir, :cfg) ? Sleipnir.cfg : PyNULL()
const utils::PyObject = isdefined(Sleipnir, :utils) ? Sleipnir.utils : PyNULL()
const workflow::PyObject = isdefined(Sleipnir, :workflow) ? Sleipnir.workflow : PyNULL()
const tasks::PyObject = isdefined(Sleipnir, :tasks) ? Sleipnir.tasks : PyNULL()
const global_tasks::PyObject = isdefined(Sleipnir, :global_tasks) ? Sleipnir.global_tasks : PyNULL()
const graphics::PyObject = isdefined(Sleipnir, :graphics) ? Sleipnir.graphics : PyNULL()
const bedtopo::PyObject = isdefined(Sleipnir, :bedtopo) ? Sleipnir.bedtopo : PyNULL()
const millan22::PyObject = isdefined(Sleipnir, :millan22) ? Sleipnir.millan22 : PyNULL()
const MBsandbox::PyObject = isdefined(Sleipnir, :MBsandbox) ? Sleipnir.MBsandbox : PyNULL()
const salem::PyObject = isdefined(Sleipnir, :salem) ? Sleipnir.salem : PyNULL()

# Essential Python libraries
const xr::PyObject = isdefined(Sleipnir, :xr) ? Sleipnir.xr : PyNULL()
const rioxarray::PyObject = isdefined(Sleipnir, :rioxarray) ? Sleipnir.rioxarray : PyNULL()
const pd::PyObject = isdefined(Sleipnir, :pd) ? Sleipnir.pd : PyNULL()

# ##############################################
# ############ HUGINN LIBRARIES ##############
# ##############################################
Expand Down
16 changes: 6 additions & 10 deletions src/parameters/SolverParameters.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,40 +38,36 @@ function SolverParameters(;
return solver_parameters
end

Base.:(==)(a::SolverParameters, b::SolverParameters) = a.solver == b.solver && a.reltol == b.reltol && a.step == b.step &&
Base.:(==)(a::SolverParameters, b::SolverParameters) = a.solver == b.solver && a.reltol == b.reltol && a.step == b.step &&
a.tstops == b.tstops && a.save_everystep == b.save_everystep && a.progress == b.progress &&
a.progress_steps == b.progress_steps

"""
Parameters(;
simulation::SimulationParameters = SimulationParameters()
physical::PhysicalParameters = PhysicalParameters()
OGGM::OGGMparameters = OGGMparameters(),
physical::PhysicalParameters = PhysicalParameters(),
simulation::SimulationParameters = SimulationParameters(),
solver::SolverParameters = SolverParameters()
)
Initialize Huginn parameters
Keyword arguments
=================
"""

function Parameters(;
physical::PhysicalParameters = PhysicalParameters(),
simulation::SimulationParameters = SimulationParameters(),
OGGM::OGGMparameters = OGGMparameters(),
solver::SolverParameters = SolverParameters()
)
)

# Build the parameters based on all the subtypes of parameters
parameters = Sleipnir.Parameters(physical, simulation, OGGM,
parameters = Sleipnir.Parameters(physical, simulation,
nothing, solver, nothing, nothing)

if parameters.simulation.multiprocessing
enable_multiprocessing(parameters)
end

oggm_config(OGGM.working_dir; oggm_processes=OGGM.workers)

return parameters
end
Expand Down
35 changes: 5 additions & 30 deletions src/setup/config.jl
Original file line number Diff line number Diff line change
@@ -1,35 +1,10 @@
function __init__()

# Create structural folders if needed
OGGM_path = joinpath(homedir(), "Python/OGGM_data")
if !isdir(OGGM_path)
mkpath(OGGM_path)
end

try
# Only load Python packages if not previously loaded by Sleipnir
if cfg == PyNULL() && workflow == PyNULL() && utils == PyNULL() && MBsandbox == PyNULL()
println("Initializing Python libraries in Huginn...")
copy!(netCDF4, pyimport("netCDF4"))
copy!(cfg, pyimport("oggm.cfg"))
copy!(utils, pyimport("oggm.utils"))
copy!(workflow, pyimport("oggm.workflow"))
copy!(tasks, pyimport("oggm.tasks"))
copy!(global_tasks, pyimport("oggm.global_tasks"))
copy!(graphics, pyimport("oggm.graphics"))
copy!(bedtopo, pyimport("oggm.shop.bedtopo"))
copy!(millan22, pyimport("oggm.shop.millan22"))
copy!(MBsandbox, pyimport("MBsandbox.mbmod_daily_oneflowline"))
copy!(salem, pyimport("salem"))
copy!(pd, pyimport("pandas"))
copy!(xr, pyimport("xarray"))
copy!(rioxarray, pyimport("rioxarray"))
end
catch e
@warn "It looks like you have not installed and/or activated the virtual Python environment. \n
Please follow the guidelines in: https://github.com/ODINN-SciML/ODINN.jl#readme"
@warn exception=(e, catch_backtrace())
end
# # Create structural folders if needed
# OGGM_path = joinpath(homedir(), "Python/OGGM_data")
# if !isdir(OGGM_path)
# mkpath(OGGM_path)
# end

end

Expand Down
4 changes: 2 additions & 2 deletions src/simulations/predictions/prediction_utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ function batch_iceflow_PDE!(glacier_idx::I, simulation::Prediction) where {I <:
params = simulation.parameters
glacier = simulation.glaciers[glacier_idx]

glacier_id = isnothing(glacier.gdir) ? "unnamed" : glacier.rgi_id
glacier_id = isnothing(glacier.rgi_id) ? "unnamed" : glacier.rgi_id
println("Processing glacier: ", glacier_id)

# Initialize glacier ice flow model
Expand Down Expand Up @@ -130,7 +130,7 @@ function batch_iceflow_PDE(glacier_idx::I, simulation::Prediction) where {I <: I
params = simulation.parameters
glacier = simulation.glaciers[glacier_idx]

glacier_id = isnothing(glacier.gdir) ? "unnamed" : glacier.rgi_id
glacier_id = isnothing(glacier.rgi_id) ? "unnamed" : glacier.rgi_id
println("Processing glacier: ", glacier_id)

# Initialize glacier ice flow model (don't needed for out-of-place? maybe a simplified version?)
Expand Down
45 changes: 22 additions & 23 deletions test/PDE_UDE_solve.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,32 @@ function pde_solve_test(; rtol::F, atol::F, save_refs::Bool=false, MB::Bool=fals

println("PDE solving with MB = $MB")
working_dir = joinpath(homedir(), "OGGM/Huginn_tests")

params = Parameters(OGGM = OGGMparameters(working_dir=working_dir,
multiprocessing=true,
workers=2,
ice_thickness_source = "Farinotti19"),
simulation = SimulationParameters(use_MB=MB,

rgi_paths = get_rgi_paths()

params = Huginn.Parameters(simulation = SimulationParameters(use_MB=MB,
velocities=false,
tspan=(2010.0, 2015.0),
working_dir = Huginn.root_dir,
test_mode = true),
test_mode = true,
rgi_paths = rgi_paths),
solver = SolverParameters(reltol=1e-12)
)
)

## Retrieving gdirs and climate for the following glaciers
## Fast version includes less glacier to reduce the amount of downloaded files and computation time on GitHub CI
## Fast version includes less glacier to reduce the amount of downloaded files and computation time on GitHub CI
if fast
rgi_ids = ["RGI60-11.03638", "RGI60-11.01450", "RGI60-08.00213", "RGI60-04.04351", "RGI60-01.02170"]
rgi_ids = ["RGI60-11.03638", "RGI60-11.01450"] #, "RGI60-08.00213", "RGI60-04.04351", "RGI60-01.02170"]
else
rgi_ids = ["RGI60-11.03638", "RGI60-11.01450", "RGI60-08.00213", "RGI60-04.04351", "RGI60-01.02170",
"RGI60-02.05098", "RGI60-01.01104", "RGI60-01.09162", "RGI60-01.00570", "RGI60-04.07051",
"RGI60-02.05098", "RGI60-01.01104", "RGI60-01.09162", "RGI60-01.00570", "RGI60-04.07051",
"RGI60-07.00274", "RGI60-07.01323", "RGI60-01.17316"]
end

if MB
model = Model(iceflow = SIA2Dmodel(params), mass_balance = TImodel1(params))
model = Huginn.Model(iceflow = SIA2Dmodel(params), mass_balance = TImodel1(params))
else
model = Model(iceflow = SIA2Dmodel(params), mass_balance = nothing)
model = Huginn.Model(iceflow = SIA2Dmodel(params), mass_balance = nothing)
end

# We retrieve some glaciers for the simulation
Expand All @@ -50,7 +49,7 @@ function pde_solve_test(; rtol::F, atol::F, save_refs::Bool=false, MB::Bool=fals
jldsave(joinpath(Huginn.root_dir, "test/data/PDE/PDE_refs_noMB.jld2"); prediction.results)
end
end

# Load reference values for the simulation
if MB
PDE_refs = load(joinpath(Huginn.root_dir, "test/data/PDE/PDE_refs_MB.jld2"))["results"]
Expand Down Expand Up @@ -86,7 +85,7 @@ function pde_solve_test(; rtol::F, atol::F, save_refs::Bool=false, MB::Bool=fals
@test all(isapprox.(result.H[end], test_ref.H[end], rtol=rtol, atol=atol))
@test all(isapprox.(result.Vx, test_ref.Vx, rtol=rtol, atol=vtol))
@test all(isapprox.(result.Vy, test_ref.Vy, rtol=rtol, atol=vtol))

end # let
end
end
Expand All @@ -95,18 +94,18 @@ end
function TI_run_test!(save_refs::Bool = false; rtol::F, atol::F) where {F <: AbstractFloat}

working_dir = joinpath(homedir(), "OGGM/Huginn_tests")
params = Parameters(OGGM = OGGMparameters(working_dir=working_dir,
multiprocessing=true,
workers=2,
ice_thickness_source = "Farinotti19"),
simulation = SimulationParameters(use_MB=true,

rgi_paths = get_rgi_paths()

params = Huginn.Parameters(simulation = SimulationParameters(use_MB=true,
velocities=false,
tspan=(2010.0, 2015.0),
working_dir = Huginn.root_dir,
test_mode = true),
test_mode = true,
rgi_paths = rgi_paths),
solver = SolverParameters(reltol=1e-8)
)
model = Model(iceflow = SIA2Dmodel(params), mass_balance = TImodel1(params))
)
model = Huginn.Model(iceflow = SIA2Dmodel(params), mass_balance = TImodel1(params))
rgi_ids = ["RGI60-11.03638"]

glacier = initialize_glaciers(rgi_ids, params)[1]
Expand Down
Binary file modified test/data/PDE/H_w_MB_ref.jld2
Binary file not shown.
Binary file modified test/data/PDE/MB_ref.jld2
Binary file not shown.
Binary file modified test/data/PDE/PDE_refs_MB.jld2
Binary file not shown.
Binary file modified test/data/PDE/PDE_refs_noMB.jld2
Binary file not shown.
Binary file modified test/data/params/solver_params_default.jld2
Binary file not shown.
Binary file modified test/data/params/solver_params_specified.jld2
Binary file not shown.
11 changes: 7 additions & 4 deletions test/halfar.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,22 @@ Arguments
"""
function unit_halfar_test(; A, n, t₀, t₁, Δx, Δy, nx, ny, h₀, r₀, rtol=0.02, atol=1.0, distance_to_border=3, save_plot=false, inplace=true)

# Get parameters for a simulation
parameters = Parameters(simulation=SimulationParameters(tspan=(t₀, t₁),
rgi_paths = get_rgi_paths()

# Get parameters for a simulation
parameters = Huginn.Parameters(simulation=SimulationParameters(tspan=(t₀, t₁),
multiprocessing=false,
use_MB=false,
use_iceflow=true,
working_dir=Huginn.root_dir),
working_dir=Huginn.root_dir,
rgi_paths=rgi_paths),
physical=PhysicalParameters(),
solver=SolverParameters(reltol=1e-12))

# Bed (it has to be flat for the Halfar solution)
B = zeros((nx,ny))

model = Model(iceflow = SIA2Dmodel(parameters), mass_balance = nothing)
model = Huginn.Model(iceflow = SIA2Dmodel(parameters), mass_balance = nothing)

# Initial condition of the glacier
R₀ = [sqrt((Δx * (i - nx/2))^2 + (Δy * (j - ny/2))^2) for i in 1:nx, j in 1:ny]
Expand Down
9 changes: 6 additions & 3 deletions test/mass_conservation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,17 @@ Arguments
"""
function unit_mass_test(; H₀, B, A, n, t_sim, Δx, Δy, rtol=0.02, save_plot=false)

rgi_paths = get_rgi_paths()

# Get parameters for a simulation
parameters = Parameters(simulation=SimulationParameters(tspan=(0.0, t_sim),
parameters = Huginn.Parameters(simulation=SimulationParameters(tspan=(0.0, t_sim),
use_MB=false,
use_iceflow=true),
use_iceflow=true,
rgi_paths=rgi_paths),
physical=PhysicalParameters(),
solver=SolverParameters(reltol=1e-12))

model = Model(iceflow = SIA2Dmodel(parameters), mass_balance = nothing)
model = Huginn.Model(iceflow = SIA2Dmodel(parameters), mass_balance = nothing)

# Surface
S = B + H₀
Expand Down
Loading

0 comments on commit 2413919

Please sign in to comment.