diff --git a/.github/workflows/minimum.yml b/.github/workflows/minimum.yml index 459f72983..0685927c0 100644 --- a/.github/workflows/minimum.yml +++ b/.github/workflows/minimum.yml @@ -22,7 +22,7 @@ jobs: matrix: julia-version: [min] julia-arch: [x64] - os: [ubuntu-22.04, macos-12, windows-2019] + os: [ubuntu-22.04, macos-13, windows-2019] steps: - uses: actions/checkout@v4 - uses: julia-actions/setup-julia@v2 diff --git a/NEWS.md b/NEWS.md index 5fc9f88f7..647d85eb5 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,7 @@ +MixedModels v4.27.1 Release Notes +============================== +- `profile` now includes a `finally` block to restore the original model even if an error occurs before profiling is complete [#795] + MixedModels v4.27.0 Release Notes ============================== - `saveoptsum` and `restoreoptsum!` now support `GeneralizedLinearMixedModel`s [#791] @@ -575,3 +579,4 @@ Package dependencies [#783]: https://github.com/JuliaStats/MixedModels.jl/issues/783 [#785]: https://github.com/JuliaStats/MixedModels.jl/issues/785 [#791]: https://github.com/JuliaStats/MixedModels.jl/issues/791 +[#795]: https://github.com/JuliaStats/MixedModels.jl/issues/795 diff --git a/Project.toml b/Project.toml index 42348b1eb..7c2c65bc5 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "MixedModels" uuid = "ff71e718-51f3-5ec2-a782-8ffcbfa3c316" author = ["Phillip Alday ", "Douglas Bates ", "Jose Bayoan Santiago Calderon "] -version = "4.27.0" +version = "4.27.1" [deps] Arrow = "69666777-d1a9-59fb-9406-91d4454c9d45" diff --git a/src/profile/profile.jl b/src/profile/profile.jl index e3cd52abc..82d71944c 100644 --- a/src/profile/profile.jl +++ b/src/profile/profile.jl @@ -35,23 +35,30 @@ value of ζ exceeds `threshold`. function profile(m::LinearMixedModel; threshold=4) isfitted(m) || refit!(m) final = copy(m.optsum.final) - tc = TableColumns(m) - val = profileσ(m, tc; threshold) # FIXME: defer creating the splines until the whole table is constructed - objective!(m, final) # restore the parameter estimates - for s in filter(s -> startswith(string(s), 'β'), keys(first(val.tbl))) - profileβj!(val, tc, s; threshold) - end - copyto!(m.optsum.final, final) - m.optsum.fmin = objective!(m, final) - for s in filter(s -> startswith(string(s), 'θ'), keys(first(val.tbl))) - profileθj!(val, s, tc; threshold) + profile = try + tc = TableColumns(m) + val = profileσ(m, tc; threshold) # FIXME: defer creating the splines until the whole table is constructed + objective!(m, final) # restore the parameter estimates + for s in filter(s -> startswith(string(s), 'β'), keys(first(val.tbl))) + profileβj!(val, tc, s; threshold) + end + copyto!(m.optsum.final, final) + m.optsum.fmin = objective!(m, final) + for s in filter(s -> startswith(string(s), 'θ'), keys(first(val.tbl))) + profileθj!(val, s, tc; threshold) + end + profileσs!(val, tc) + MixedModelProfile(m, Table(val.tbl), val.fwd, val.rev) + catch ex + @error "Exception occurred in profiling; aborting..." + rethrow() + finally + objective!(m, final) # restore the parameter estimates + copyto!(m.optsum.final, final) + m.optsum.fmin = objective(m) + m.optsum.sigma = nothing end - profileσs!(val, tc) - objective!(m, final) # restore the parameter estimates - copyto!(m.optsum.final, final) - m.optsum.fmin = objective(m) - m.optsum.sigma = nothing - return MixedModelProfile(m, Table(val.tbl), val.fwd, val.rev) + return profile end """ diff --git a/test/pls.jl b/test/pls.jl index 98d239ec3..95b1e877b 100644 --- a/test/pls.jl +++ b/test/pls.jl @@ -725,6 +725,13 @@ end # very loose tolerance for unstable fit # but this is a convenient test of rankUpdate!(::UniformBlockDiagonal) @test isapprox(m.θ, θnlopt; atol=5e-2) + + @testset "profile" begin + # TODO: actually handle the case here so that it doesn't error and + # create a separate test of the error handling code + @test_logs((:error, "Exception occurred in profiling; aborting..."), + @test_throws Exception profile(last(models(:oxide)))) + end end @testset "Rank deficient" begin