Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "InferenceObjects"
uuid = "b5cf5a8d-e756-4ee3-b014-01d49d192c00"
authors = ["Seth Axen <seth.axen@gmail.com> and contributors"]
version = "0.4.15"
version = "0.4.16"

[deps]
ANSIColoredPrinters = "a4c015fc-c6ff-483c-b24f-f7ea428134e9"
Expand All @@ -25,7 +25,7 @@ InferenceObjectsPosteriorStatsExt = ["PosteriorStats", "StatsBase"]
ANSIColoredPrinters = "0.0.1"
ArviZExampleData = "0.3"
Dates = "1"
DimensionalData = "0.27, 0.28, 0.29"
DimensionalData = "0.27, 0.28, 0.29, 0.30"
EvoTrees = "0.16"
MCMCDiagnosticTools = "0.3.4"
MLJBase = "1"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module InferenceObjectsMCMCDiagnosticToolsExt

using Base: @doc
using DimensionalData: DimensionalData, Dimensions, LookupArrays
using DimensionalData: DimensionalData, Dimensions
using InferenceObjects: InferenceObjects, Random
using MCMCDiagnosticTools: MCMCDiagnosticTools

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module InferenceObjectsNCDatasetsExt

using DimensionalData: DimensionalData, Dimensions, LookupArrays
using DimensionalData: DimensionalData, Dimensions, Lookups
using NCDatasets: NCDatasets
using InferenceObjects

Expand All @@ -20,7 +20,7 @@ function _from_netcdf(ds, load_mode)
index = collect(group[dim_name])
if index == eachindex(index)
# discard the index if it is just the default
index = LookupArrays.NoLookup()
index = Lookups.NoLookup()
end
return Symbol(dim_name) => Dimensions.Dim{Symbol(dim_name)}(index)
end...
Expand All @@ -36,7 +36,7 @@ function _from_netcdf(ds, load_mode)
else
var.attrib
end
metadata = isempty(attrib) ? LookupArrays.NoMetadata() : attrib
metadata = isempty(attrib) ? Lookups.NoMetadata() : attrib
da = DimensionalData.DimArray(vals, dims; name, metadata)
return name => da
end...
Expand Down Expand Up @@ -89,7 +89,7 @@ function InferenceObjects.to_netcdf(
for dim in Dimensions.dims(group_data)
dim_name = String(Dimensions.name(dim))
NCDatasets.defDim(group_ds, dim_name, length(dim))
index = LookupArrays.index(group_data, dim)
index = parent(Dimensions.lookup(group_data, dim))
var = NCDatasets.defVar(group_ds, dim_name, eltype(index), (dim_name,))
copyto!(var, index)
end
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module InferenceObjectsPosteriorStatsExt

using Base: @doc
using DimensionalData: DimensionalData, Dimensions, LookupArrays
using DimensionalData: DimensionalData, Dimensions
using InferenceObjects: InferenceObjects
using PosteriorStats: PosteriorStats
using StatsBase: StatsBase
Expand Down
2 changes: 1 addition & 1 deletion src/InferenceObjects.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module InferenceObjects

using ANSIColoredPrinters: ANSIColoredPrinters
using Dates: Dates
using DimensionalData: DimensionalData, Dimensions, LookupArrays
using DimensionalData: DimensionalData, Dimensions, Lookups
using Random: Random
using Tables: Tables

Expand Down
33 changes: 19 additions & 14 deletions src/dataset.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,26 @@ that implements the same interface as `DimensionalData.DimStack` and has identic
In most cases, use [`convert_to_dataset`](@ref) to create a `Dataset` instead of directly
using a constructor.
"""
struct Dataset{K,T,N,L,D<:DimensionalData.AbstractDimStack{K,T,N,L}} <:
DimensionalData.AbstractDimStack{K,T,N,L}
data::D
end
Dataset
@static if pkgversion(DimensionalData) ≥ v"0.30.0"
struct Dataset{K,T,N,L,D,Data<:DimensionalData.AbstractDimStack{K,T,N,L,D}} <:
DimensionalData.AbstractDimStack{K,T,N,L,D}
data::Data
end
else # DimensionalData < 0.30
struct Dataset{K,T,N,L,Data<:DimensionalData.AbstractDimStack{K,T,N,L}} <:
DimensionalData.AbstractDimStack{K,T,N,L}
data::Data
end

function Dataset{K,T,N}(
data::L, dims, refdims, layerdims, metadata, layermetadata
) where {K,T,N,L}
data = DimensionalData.DimStack{K,T,N}(
data, dims, refdims, layerdims, metadata, layermetadata
)
return Dataset{K,T,N,L,typeof(data)}(data)
function Dataset{K,T,N}(
data::L, dims, refdims, layerdims, metadata, layermetadata
) where {K,T,N,L}
data = DimensionalData.DimStack{K,T,N}(
data, dims, refdims, layerdims, metadata, layermetadata
)
return Dataset{K,T,N,L,typeof(data)}(data)
end
end
Dataset(args...; kwargs...) = Dataset(DimensionalData.DimStack(args...; kwargs...))
Dataset(data::Dataset) = data
Expand Down Expand Up @@ -123,9 +131,6 @@ end

DimensionalData.modify(f, s::Dataset) = Dataset(DimensionalData.modify(f, parent(s)))

# Warning: this is not an API function and probably should be implemented abstractly upstream
DimensionalData.show_after(io, mime, ::Dataset) = nothing

attributes(data::DimensionalData.AbstractDimStack) = DimensionalData.metadata(data)

Base.convert(T::Type{<:DimensionalData.DimStack}, data::Dataset) = convert(T, parent(data))
Expand Down
20 changes: 10 additions & 10 deletions src/dimensions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ has_all_sample_dims(dims) = all(Dimensions.hasdim(dims, DEFAULT_SAMPLE_DIMS))

# Like Dimensions.name2dim but doesn't allow users to inject their own dimensions using
# Dimensions.@dim. See https://github.com/arviz-devs/InferenceObjects.jl/issues/37
_name2dim(d::Symbol) = Dimensions.Dim{d}(LookupArrays.NoLookup())
_name2dim(d::Symbol) = Dimensions.Dim{d}(Lookups.NoLookup())
_name2dim(d::Tuple) = map(_name2dim, d)
_name2dim(d) = d

# make sure dim has a lookup value accessible with `val`
_valdim(d) = d
_valdim(d::Type{<:Dimensions.Dimension}) = d(LookupArrays.NoLookup())
_valdim(d::Type{<:Dimensions.Dimension}) = d(Lookups.NoLookup())

"""
as_dimension(dim, coords, axis) -> DimensionsionalData.Dimension
Expand All @@ -31,8 +31,8 @@ Convert `dim`, `coords`, and `axis` to a `Dimension` object.
"""
function as_dimension(dim, coords, axis)
cdim = _valdim(_name2dim(dim))
val = LookupArrays.val(cdim)
inds = val isa Union{Colon,LookupArrays.NoLookup} ? axis : val
val = Lookups.val(cdim)
inds = val isa Union{Colon,Lookups.NoLookup} ? axis : val
coords_inds = get(coords, Dimensions.name(cdim), inds)
return Dimensions.rebuild(cdim, coords_inds)
end
Expand Down Expand Up @@ -79,7 +79,7 @@ function generate_dims(array, name; dims=(), coords=(;), default_dims=())
end
dims_all = (default_dims..., dims_named...)
# default to the axes if no coords are provided
axes_all = map(_ -> LookupArrays.NoLookup(), dims_all)
axes_all = map(_ -> Lookups.NoLookup(), dims_all)
T = NTuple{ndims(array),Dimensions.Dimension}
dims_with_coords = as_dimension.(dims_all, Ref(coords), axes_all)::T
return Dimensions.format(dims_with_coords, array)::T
Expand Down Expand Up @@ -107,20 +107,20 @@ function array_to_dimarray(array::DimensionalData.AbstractDimArray, name; kwargs
end

"""
AsSlice{T<:LookupArrays.Selector} <: LookupArrays.Selector{T}
AsSlice{T<:Lookups.Selector} <: Lookups.Selector{T}

AsSlice(selector)

Selector that ensures selected indices are arrays so that slicing occurs.

This is useful to ensure that selecting a single index still returns an array.
"""
struct AsSlice{T<:LookupArrays.Selector} <: LookupArrays.Selector{T}
struct AsSlice{T<:Lookups.Selector} <: Lookups.Selector{T}
val::T
end

function LookupArrays.selectindices(l::LookupArrays.LookupArray, sel::AsSlice; kw...)
i = LookupArrays.selectindices(l, LookupArrays.val(sel); kw...)
function Lookups.selectindices(l::Lookups.LookupArray, sel::AsSlice; kw...)
i = Lookups.selectindices(l, Lookups.val(sel); kw...)
inds = i isa AbstractVector ? i : [i]
return inds
end
Expand All @@ -132,4 +132,4 @@ Convert `index` to a collection of indices or a selector representing such a col
"""
index_to_indices(i) = i
index_to_indices(i::Int) = [i]
index_to_indices(sel::LookupArrays.Selector) = AsSlice(sel)
index_to_indices(sel::Lookups.Selector) = AsSlice(sel)
4 changes: 4 additions & 0 deletions src/inference_data.jl
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ julia> idata_cat1.posterior
├────────────────────────────────────────────────── metadata ┤
Dict{String, Any} with 1 entry:
"created_at" => "2025-07-25T10:11:18.92"
└────────────────────────────────────────────────────────────┘
```

Alternatively, we can concatenate along a new `run` dimension, which will be created.
Expand All @@ -342,6 +343,7 @@ julia> idata_cat2.posterior
├───────────────────────────────────────────────────────── metadata ┤
Dict{String, Any} with 1 entry:
"created_at" => "2025-07-25T10:11:18.92"
└───────────────────────────────────────────────────────────────────┘
```

We can also concatenate only a subset of groups and merge the rest, which is useful when
Expand Down Expand Up @@ -374,6 +376,7 @@ julia> idata_cat3.posterior
├───────────────────────────────────────────────────────── metadata ┤
Dict{String, Any} with 1 entry:
"created_at" => "2025-07-25T10:11:18.92"
└───────────────────────────────────────────────────────────────────┘

julia> idata_cat3.observed_data
┌ 10-element Dataset ┐
Expand All @@ -384,6 +387,7 @@ julia> idata_cat3.observed_data
├────────────────────────────────────────────┴ metadata ┐
Dict{String, Any} with 1 entry:
"created_at" => "2025-07-25T10:11:18.951"
└───────────────────────────────────────────────────────┘
```
"""
function Base.cat(data::InferenceData, others::InferenceData...; groups=keys(data), dims)
Expand Down
5 changes: 3 additions & 2 deletions test/dataset.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using InferenceObjects, DimensionalData, Test
using DimensionalData: Lookups

@testset "dataset" begin
@testset "Dataset" begin
Expand Down Expand Up @@ -118,9 +119,9 @@ using InferenceObjects, DimensionalData, Test
end

@testset "DimensionalData.set" begin
ds2 = DimensionalData.set(ds; ydim1=LookupArrays.Sampled([-2, 2]))
ds2 = DimensionalData.set(ds, :ydim1 => Lookups.Sampled([-2, 2]))
@test ds2 isa Dataset
@test DimensionalData.lookup(ds2, :ydim1) == [-2, 2]
@test parent(DimensionalData.lookup(ds2, :ydim1)) == [-2, 2]
@test DimensionalData.data(ds2) == DimensionalData.data(ds)
end
end
Expand Down
35 changes: 19 additions & 16 deletions test/dimensions.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using InferenceObjects, DimensionalData, OffsetArrays, Test
using DimensionalData.LookupArrays
using DimensionalData.Lookups

Dimensions.@dim foo "foo"

Expand Down Expand Up @@ -69,24 +69,27 @@ Dimensions.@dim foo "foo"
)
@test gdims isa NTuple{4,Dim}
@test Dimensions.name(gdims) === (:x_dim_1, :x_dim_2, :x_dim_3, :x_dim_4)
@test Dimensions.index(gdims) == (11:20, 0:3, -1:0, 2:4)
@test Dimensions.val.(Dimensions.dims(gdims)) isa NTuple{4,LookupArrays.NoLookup}
glooks = Dimensions.lookup(gdims)
@test glooks isa NTuple{4,NoLookup}
@test parent.(glooks) == (11:20, 0:3, -1:0, 2:4)

gdims = @inferred NTuple{4,Dimensions.Dimension} InferenceObjects.generate_dims(
x, :y; dims=(:a, :b)
)
@test gdims isa NTuple{4,Dim}
@test Dimensions.name(gdims) === (:a, :b, :y_dim_3, :y_dim_4)
@test Dimensions.index(gdims) == (11:20, 0:3, -1:0, 2:4)
@test Dimensions.val.(Dimensions.dims(gdims)) isa NTuple{4,LookupArrays.NoLookup}
glooks = Dimensions.lookup(gdims)
@test glooks isa NTuple{4,NoLookup}
@test parent.(glooks) == (11:20, 0:3, -1:0, 2:4)

gdims = @inferred NTuple{4,Dimensions.Dimension} InferenceObjects.generate_dims(
x, :z; dims=(:c, :d), default_dims=(:draw, :chain)
)
@test gdims isa NTuple{4,Dim}
@test Dimensions.name(gdims) === (:draw, :chain, :c, :d)
@test Dimensions.index(gdims) == (11:20, 0:3, -1:0, 2:4)
@test Dimensions.val.(Dimensions.dims(gdims)) isa NTuple{4,LookupArrays.NoLookup}
glooks = Dimensions.lookup(gdims)
@test glooks isa NTuple{4,NoLookup}
@test parent.(glooks) == (11:20, 0:3, -1:0, 2:4)

x = randn(2, 3)
InferenceObjects.generate_dims(x, :x; dims=(:a, :b))
Expand All @@ -109,15 +112,15 @@ Dimensions.@dim foo "foo"
gdims = Dimensions.dims(da)
@test gdims isa NTuple{4,Dim}
@test Dimensions.name(gdims) === (:x_dim_1, :x_dim_2, :x_dim_3, :x_dim_4)
@test Dimensions.index(gdims) == (11:20, 0:3, -1:0, 2:4)
@test parent.(Dimensions.lookup(gdims)) == (11:20, 0:3, -1:0, 2:4)

da = @inferred DimArray InferenceObjects.array_to_dimarray(x, :y; dims=(:a, :b))
@test da == x
@test DimensionalData.name(da) === :y
gdims = Dimensions.dims(da)
@test gdims isa NTuple{4,Dim}
@test Dimensions.name(gdims) === (:a, :b, :y_dim_3, :y_dim_4)
@test Dimensions.index(gdims) == (11:20, 0:3, -1:0, 2:4)
@test parent.(Dimensions.lookup(gdims)) == (11:20, 0:3, -1:0, 2:4)

da = @inferred DimArray InferenceObjects.array_to_dimarray(
x, :z; dims=(:c, :d), default_dims=(:draw, :chain)
Expand All @@ -127,7 +130,7 @@ Dimensions.@dim foo "foo"
gdims = Dimensions.dims(da)
@test gdims isa NTuple{4,Dim}
@test Dimensions.name(gdims) === (:draw, :chain, :c, :d)
@test Dimensions.index(gdims) == (11:20, 0:3, -1:0, 2:4)
@test parent.(Dimensions.lookup(gdims)) == (11:20, 0:3, -1:0, 2:4)

v = randn(1_000)
da = @inferred DimArray InferenceObjects.array_to_dimarray(
Expand All @@ -138,7 +141,7 @@ Dimensions.@dim foo "foo"
gdims = Dimensions.dims(da)
@test gdims isa NTuple{2,Dim}
@test Dimensions.name(gdims) === (:draw, :chain)
@test Dimensions.index(gdims) == (1:1000, 1:1)
@test parent.(Dimensions.lookup(gdims)) == (1:1000, 1:1)

s = fill(1) # 0-dimensional array
da = @inferred DimArray InferenceObjects.array_to_dimarray(
Expand All @@ -149,18 +152,18 @@ Dimensions.@dim foo "foo"
gdims = Dimensions.dims(da)
@test gdims isa NTuple{2,Dim}
@test Dimensions.name(gdims) === (:draw, :chain)
@test Dimensions.index(gdims) == (1:1, 1:1)
@test parent.(Dimensions.lookup(gdims)) == (1:1, 1:1)
end

@testset "AsSlice" begin
da = DimArray(randn(2), Dim{:a}(["foo", "bar"]))
@test da[a=At("foo")] == da[1]
da_sel = @inferred da[a=InferenceObjects.AsSlice(At("foo"))]
@test da[a = At("foo")] == da[1]
da_sel = @inferred da[a = InferenceObjects.AsSlice(At("foo"))]
@test da_sel isa DimArray
@test Dimensions.dims(da_sel) == (Dim{:a}(["foo"]),)
@test da_sel == da[a=At(["foo"])]
@test da_sel == da[a = At(["foo"])]

da_sel = @inferred da[a=At(["foo", "bar"])]
da_sel = @inferred da[a = At(["foo", "bar"])]
@test da_sel isa DimArray
@test Dimensions.dims(da_sel) == Dimensions.dims(da)
@test da_sel == da
Expand Down
27 changes: 15 additions & 12 deletions test/inference_data.jl
Original file line number Diff line number Diff line change
Expand Up @@ -57,26 +57,29 @@ using InferenceObjects, DimensionalData, Test
@test idata[1] === posterior
@test idata[2] === prior

idata_sel = idata[dima=At(2:3), dimb=At(6)]
idata_sel = idata[dima = At(2:3), dimb = At(6)]
@test idata_sel isa InferenceData
@test InferenceObjects.groupnames(idata_sel) === InferenceObjects.groupnames(idata)
@test Dimensions.index(idata_sel.posterior, :dima) == 2:3
@test Dimensions.index(idata_sel.prior, :dima) == 2:3
@test Dimensions.index(idata_sel.posterior, :dimb) == [6]
@test Dimensions.index(idata_sel.prior, :dimb) == [6]
@test parent(Dimensions.lookup(idata_sel.posterior, :dima)) == 2:3
@test parent(Dimensions.lookup(idata_sel.prior, :dima)) == 2:3
@test parent(Dimensions.lookup(idata_sel.posterior, :dimb)) == [6]
@test parent(Dimensions.lookup(idata_sel.prior, :dimb)) == [6]

if VERSION ≥ v"1.7"
idata_sel = idata[(:posterior, :observed_data), dimy=1, dimb=1, shared=At("s1")]
idata_sel = idata[
(:posterior, :observed_data), dimy = 1, dimb = 1, shared = At("s1")
]
@test idata_sel isa InferenceData
@test InferenceObjects.groupnames(idata_sel) === (:posterior, :observed_data)
@test Dimensions.index(idata_sel.posterior, :dima) == coords.dima
@test Dimensions.index(idata_sel.posterior, :dimb) == coords.dimb[[1]]
@test Dimensions.index(idata_sel.posterior, :shared) == ["s1"]
@test Dimensions.index(idata_sel.observed_data, :dimy) == coords.dimy[[1]]
@test Dimensions.index(idata_sel.observed_data, :shared) == ["s1"]
@test parent(Dimensions.lookup(idata_sel.posterior, :dima)) == coords.dima
@test parent(Dimensions.lookup(idata_sel.posterior, :dimb)) == coords.dimb[[1]]
@test parent(Dimensions.lookup(idata_sel.posterior, :shared)) == ["s1"]
@test parent(Dimensions.lookup(idata_sel.observed_data, :dimy)) ==
coords.dimy[[1]]
@test parent(Dimensions.lookup(idata_sel.observed_data, :shared)) == ["s1"]
end

ds_sel = idata[:posterior, chain=1]
ds_sel = idata[:posterior, chain = 1]
@test ds_sel isa Dataset
@test !hasdim(ds_sel, :chain)

Expand Down
Loading
Loading