Skip to content
Merged
5 changes: 1 addition & 4 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ concurrency:

jobs:
test:
name: ${{ matrix.pkg.name }} - Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }}
name: ${{ matrix.pkg.name }} - Julia ${{ matrix.version }} - ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
Expand All @@ -25,8 +25,6 @@ jobs:
- ubuntu-latest
- windows-latest
- macOS-latest
arch:
- x64
pkg:
- name: SSMProblems
dir: './SSMProblems'
Expand All @@ -40,7 +38,6 @@ jobs:
uses: julia-actions/setup-julia@v3
with:
version: ${{ matrix.version }}
arch: ${{ matrix.arch }}

- name: Cache artifacts
uses: julia-actions/cache@v3
Expand Down
88 changes: 86 additions & 2 deletions GeneralisedFilters/docs/literate.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,90 @@ Pkg.activate(EXAMPLEPATH)
Pkg.instantiate()
using Literate: Literate

# Convert to markdown and notebook
# Insert an "Open in Colab" badge (after the title) that opens the notebook published to
# the gh-pages docs. The version subdir matches Documenter's deploy target: `previews/PR<n>`
# for pull-request previews, the tag (e.g. `v1.2.3`) for tagged releases, otherwise `dev`.
const REPO = "TuringLang/SSMProblems.jl"
const PKG = basename(dirname(@__DIR__))

function docs_subfolder()
ref = get(ENV, "GITHUB_REF", "")
if get(ENV, "GITHUB_EVENT_NAME", "") == "pull_request"
pr = match(r"^refs/pull/(\d+)/", ref)
pr === nothing || return string("previews/PR", only(pr.captures))
end
tag = match(r"^refs/tags/(.+)$", ref)
tag === nothing || return only(tag.captures)
return "dev"
end

const COLAB_BADGE = string(
"# [![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)]",
"(https://colab.research.google.com/github/",
REPO,
"/blob/gh-pages/",
PKG,
"/",
docs_subfolder(),
"/examples/",
EXAMPLE,
".ipynb)",
)

function add_colab_badge(content)
lines = string.(split(content, '\n'))
idx = findfirst(line -> startswith(line, "# # "), lines)
idx === nothing && return string(COLAB_BADGE, "\n#\n", content)
insert!(lines, idx + 1, "#")
insert!(lines, idx + 2, COLAB_BADGE)
return join(lines, '\n')
end

const SCRIPTJL = joinpath(EXAMPLEPATH, "script.jl")
Literate.markdown(SCRIPTJL, OUTDIR; name=EXAMPLE, execute=true)

# Top-level `using`/`import` package names, so the notebook can install them on Colab.
function script_packages(path)
pkgs = String[]
for line in eachline(path)
m = match(r"^\s*(?:using|import)\s+(.+)", line)
m === nothing && continue
for part in split(first(split(m.captures[1], ':')), ',')
token = first(split(strip(part), r"\s+as\s+"))
name = strip(first(split(token, '.')))
isempty(name) || name in pkgs || push!(pkgs, String(name))
end
end
return sort(pkgs)
end

# Notebook postprocess: use a generic Julia kernel (so Colab picks its default Julia
# runtime, with no pinned version) and prepend a single Pkg.add for all imported packages
# so the notebook runs on a fresh Colab runtime.
function prepare_notebook(nb)
nb["metadata"]["kernelspec"] = Dict(
"display_name" => "Julia", "language" => "julia", "name" => "julia"
)
packages = script_packages(SCRIPTJL)
if !isempty(packages)
setup = Dict(
"cell_type" => "code",
"execution_count" => nothing,
"metadata" => Dict(),
"outputs" => [],
"source" =>
["import Pkg\n", string("Pkg.add([", join(repr.(packages), ", "), "])")],
)
idx = findfirst(cell -> cell["cell_type"] == "code", nb["cells"])
insert!(nb["cells"], something(idx, lastindex(nb["cells"]) + 1), setup)
end
return nb
end

# Convert to markdown and notebook
Literate.markdown(SCRIPTJL, OUTDIR; name=EXAMPLE, execute=true, preprocess=add_colab_badge)
# Also emit a runnable notebook; Documenter copies it into the deployed site, under the
# versioned docs dir (dev/, vX.Y/, or previews/PR<n>/ for PR previews). The badge goes on
# the rendered page only; the notebook gets a Colab setup cell instead.
Literate.notebook(
SCRIPTJL, OUTDIR; name=EXAMPLE, execute=false, postprocess=prepare_notebook
)
6 changes: 5 additions & 1 deletion GeneralisedFilters/docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ mkpath(EXAMPLES_OUT)

# Install and precompile all packages
# Workaround for https://github.com/JuliaLang/Pkg.jl/issues/2219
examples = filter!(isdir, readdir(joinpath(@__DIR__, "..", "examples"); join=true))
# Only build directories that ship a Literate `script.jl`; other example dirs
# (e.g. script-only scratch examples) are skipped rather than failing the build.
examples = filter(readdir(joinpath(@__DIR__, "..", "examples"); join=true)) do path
return isdir(path) && isfile(joinpath(path, "script.jl"))
end
above = joinpath(@__DIR__, "..")
ssmproblems_path = joinpath(above, "..", "SSMProblems")
let script = "using Pkg; Pkg.activate(ARGS[1]); Pkg.develop(path=\"$(above)\"); Pkg.develop(path=\"$(ssmproblems_path)\"); Pkg.instantiate()"
Expand Down
10 changes: 6 additions & 4 deletions GeneralisedFilters/examples/trend-inflation/utilities.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ end
# for normal collections
mean_path(paths, states) = _mean_path(identity, paths, states)

# for rao blackwellised particles
function mean_path(paths::Vector{Vector{T}}, states) where {T<:GeneralisedFilters.RBState}
zs = _mean_path(s -> getproperty.(getproperty.(s, :z), :μ), paths, states)
xs = _mean_path(s -> getproperty.(s, :x), paths, states)
# for rao blackwellised particles; `get_ancestry` returns `ReferenceTrajectory`s, which we
# collect into plain vectors before extracting per-time-step state components
function mean_path(paths::AbstractVector{<:GeneralisedFilters.ReferenceTrajectory}, states)
trajectories = map(collect, paths)
zs = _mean_path(s -> getproperty.(getproperty.(s, :z), :μ), trajectories, states)
xs = _mean_path(s -> getproperty.(s, :x), trajectories, states)
return zs, xs
end

Expand Down
88 changes: 86 additions & 2 deletions SSMProblems/docs/literate.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,90 @@ Pkg.activate(EXAMPLEPATH)
Pkg.instantiate()
using Literate: Literate

# Convert to markdown and notebook
# Insert an "Open in Colab" badge (after the title) that opens the notebook published to
# the gh-pages docs. The version subdir matches Documenter's deploy target: `previews/PR<n>`
# for pull-request previews, the tag (e.g. `v1.2.3`) for tagged releases, otherwise `dev`.
const REPO = "TuringLang/SSMProblems.jl"
const PKG = basename(dirname(@__DIR__))

function docs_subfolder()
ref = get(ENV, "GITHUB_REF", "")
if get(ENV, "GITHUB_EVENT_NAME", "") == "pull_request"
pr = match(r"^refs/pull/(\d+)/", ref)
pr === nothing || return string("previews/PR", only(pr.captures))
end
tag = match(r"^refs/tags/(.+)$", ref)
tag === nothing || return only(tag.captures)
return "dev"
end

const COLAB_BADGE = string(
"# [![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)]",
"(https://colab.research.google.com/github/",
REPO,
"/blob/gh-pages/",
PKG,
"/",
docs_subfolder(),
"/examples/",
EXAMPLE,
".ipynb)",
)

function add_colab_badge(content)
lines = string.(split(content, '\n'))
idx = findfirst(line -> startswith(line, "# # "), lines)
idx === nothing && return string(COLAB_BADGE, "\n#\n", content)
insert!(lines, idx + 1, "#")
insert!(lines, idx + 2, COLAB_BADGE)
return join(lines, '\n')
end

const SCRIPTJL = joinpath(EXAMPLEPATH, "script.jl")
Literate.markdown(SCRIPTJL, OUTDIR; name=EXAMPLE, execute=true)

# Top-level `using`/`import` package names, so the notebook can install them on Colab.
function script_packages(path)
pkgs = String[]
for line in eachline(path)
m = match(r"^\s*(?:using|import)\s+(.+)", line)
m === nothing && continue
for part in split(first(split(m.captures[1], ':')), ',')
token = first(split(strip(part), r"\s+as\s+"))
name = strip(first(split(token, '.')))
isempty(name) || name in pkgs || push!(pkgs, String(name))
end
end
return sort(pkgs)
end

# Notebook postprocess: use a generic Julia kernel (so Colab picks its default Julia
# runtime, with no pinned version) and prepend a single Pkg.add for all imported packages
# so the notebook runs on a fresh Colab runtime.
function prepare_notebook(nb)
nb["metadata"]["kernelspec"] = Dict(
"display_name" => "Julia", "language" => "julia", "name" => "julia"
)
packages = script_packages(SCRIPTJL)
if !isempty(packages)
setup = Dict(
"cell_type" => "code",
"execution_count" => nothing,
"metadata" => Dict(),
"outputs" => [],
"source" =>
["import Pkg\n", string("Pkg.add([", join(repr.(packages), ", "), "])")],
)
idx = findfirst(cell -> cell["cell_type"] == "code", nb["cells"])
insert!(nb["cells"], something(idx, lastindex(nb["cells"]) + 1), setup)
end
return nb
end

# Convert to markdown and notebook
Literate.markdown(SCRIPTJL, OUTDIR; name=EXAMPLE, execute=true, preprocess=add_colab_badge)
# Also emit a runnable notebook; Documenter copies it into the deployed site, under the
# versioned docs dir (dev/, vX.Y/, or previews/PR<n>/ for PR previews). The badge goes on
# the rendered page only; the notebook gets a Colab setup cell instead.
Literate.notebook(
SCRIPTJL, OUTDIR; name=EXAMPLE, execute=false, postprocess=prepare_notebook
)
Loading