Skip to content

Commit

Permalink
Merge 1b6f600 into 2a11716
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaqz authored Aug 25, 2024
2 parents 2a11716 + 1b6f600 commit d7ae55b
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 19 deletions.
4 changes: 4 additions & 0 deletions src/Dimensions/set.jl
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
const DimSetters = Union{LookupSetters,Type,UnionAll,Dimension,Symbol}

set(dim::Dimension, ::Type{T}) where T = set(dim, T())
set(dims::DimTuple, ::Type{T}) where T = set(dims, T())
set(dim::Dimension, x::DimSetters) = _set(dim, x)
set(dims_::DimTuple, args::Union{Dimension,DimTuple,Pair}...; kw...) =
_set(dims_, args...; kw...)
set(dims::DimTuple, l::Lookup) = set(dims, map(d -> basedims(d) => l, dims)...)
set(dims::DimTuple, l::LookupTrait) = set(dims, map(d -> basedims(d) => l, dims)...)
# Convert args/kw to dims and set
_set(dims_::DimTuple, args::Dimension...; kw...) = _set(dims_, (args..., kw2dims(kw)...))
# Convert pairs to wrapped dims and set
Expand Down
2 changes: 2 additions & 0 deletions src/Lookups/lookup_traits.jl
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,8 @@ struct AutoStep end
struct AutoBounds end
struct AutoDim end

Base.step(::AutoSpan) = AutoStep()

"""
Regular <: Span
Expand Down
22 changes: 22 additions & 0 deletions src/Lookups/set.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
const LookupSetters = Union{AllMetadata,Lookup,LookupTrait,Nothing,AbstractArray}

set(lookup::Lookup, x::LookupSetters) = _set(lookup, x)
set(lookup::Lookup, ::Type{T}) where T = _set(lookup, T())

# _set(lookup::Lookup, newlookup::Lookup) = lookup
_set(lookup::AbstractCategorical, newlookup::AutoLookup) = begin
Expand Down Expand Up @@ -62,6 +64,26 @@ _set(order::Order, neworder::Order) = neworder
_set(order::Order, neworder::AutoOrder) = order

# Span
_set(lookup::AbstractSampled, ::Irregular{AutoBounds}) = begin
bnds = if parent(lookup) isa AutoValues || span(lookup) isa AutoSpan
AutoBounds()
else
bounds(lookup)
end
rebuild(lookup; span=Irregular(bnds))
end
_set(lookup::AbstractSampled, ::Regular{AutoStep}) = begin
stp = if span(lookup) isa AutoSpan || step(lookup) isa AutoStep
if parent(lookup) isa AbstractRange
step(parent(lookup))
else
AutoStep()
end
else
step(lookup)
end
rebuild(lookup; span=Regular(stp))
end
_set(lookup::AbstractSampled, span::Span) = rebuild(lookup; span=span)
_set(lookup::AbstractSampled, span::AutoSpan) = lookup
_set(span::Span, newspan::Span) = newspan
Expand Down
30 changes: 21 additions & 9 deletions src/set.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ of a [`Lookup`](@ref) to `set` - there is no ambiguity.
To set fields of a `Lookup` you need to specify the dimension. This can be done
using `X => val` pairs, `X = val` keyword arguments, or `X(val)` wrapped arguments.
You can also set the fields of all dimensions by simply passing a single [`Lookup`](@ref)
or lookup trait - it will be set for all dimensions.
When a `Dimension` or `Lookup` is passed to `set` to replace the
existing ones, fields that are not set will keep their original values.
Expand Down Expand Up @@ -114,27 +117,36 @@ julia> set(da, :custom => DD.Irregular(10, 12), Z => DD.Regular(9.9))
```
"""
function set end
set(A::DimArrayOrStack, x::T) where {T<:Union{Lookup,LookupTrait}} = _onlydimerror(x)
set(x::DimArrayOrStack, ::Type{T}) where T = set(x, T())
# Types are constructed
Base.@assume_effects :effect_free set(x::DimArrayOrStack, ::Type{T}) where T = set(x, T())

set(A::AbstractDimStack, x::Lookup) = Lookups._cantseterror(A, x)
set(A::AbstractDimArray, x::Lookup) = Lookups._cantseterror(A, x)
set(A, x) = Lookups._cantseterror(A, x)
set(A::DimArrayOrStack, args::Union{Dimension,DimTuple,Pair}...; kw...) =
# Dimensions and pairs are set for dimensions
Base.@assume_effects :effect_free set(A::DimArrayOrStack, args::Union{Dimension,DimTuple,Pair}...; kw...) =
rebuild(A, data(A), set(dims(A), args...; kw...))
set(A::AbstractDimArray, newdata::AbstractArray) = begin
# Single traits are set for all dimensions
Base.@assume_effects :effect_free set(A::DimArrayOrStack, x::LookupTrait) =
set(A, map(d -> basedims(d) => x, dims(A))...)
# Single lookups are set for all dimensions
Base.@assume_effects :effect_free set(A::AbstractDimArray, x::Lookup) =
set(A, map(d -> basedims(d) => x, dims(A))...)
Base.@assume_effects :effect_free set(A::AbstractDimStack, x::Lookup) =
set(A, map(d -> basedims(d) => x, dims(A))...)
# Arrays are set as data for AbstractDimArray
Base.@assume_effects :effect_free set(A::AbstractDimArray, newdata::AbstractArray) = begin
axes(A) == axes(newdata) || _axiserr(A, newdata)
rebuild(A; data=newdata)
end
set(s::AbstractDimStack, newdata::NamedTuple) = begin
# NamedTuples are set as data for AbstractDimStack
Base.@assume_effects :effect_free set(s::AbstractDimStack, newdata::NamedTuple) = begin
dat = data(s)
keys(dat) === keys(newdata) || _keyerr(keys(dat), keys(newdata))
map(dat, newdata) do d, nd
axes(d) == axes(nd) || _axiserr(d, nd)
end
rebuild(s; data=newdata)
end
# Other things error
Base.@assume_effects :effect_free set(A, x) = Lookups._cantseterror(A, x)

@noinline _onlydimerror(x) = throw(ArgumentError("Can only set $(typeof(x)) for a dimension. Specify which dimension you mean with `X => property`"))
@noinline _axiserr(a, b) = throw(ArgumentError("passed in axes $(axes(b)) do not match the currect axes $(axes(a))"))
@noinline _keyerr(ka, kb) = throw(ArgumentError("keys $ka and $kb do not match"))
30 changes: 20 additions & 10 deletions test/set.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ a = [1 2; 3 4]
dimz = (X(143.0:2.0:145.0; lookup=Sampled(order=ForwardOrdered()), metadata=Metadata(Dict(:meta => "X"))),
Y(-38.0:2.0:-36.0; lookup=Sampled(order=ForwardOrdered()), metadata=Metadata(Dict(:meta => "Y"))))
da = DimArray(a, dimz; name=:test)
interval_da = set(da, X=Intervals(), Y=Intervals())

a2 = [1 2 3 4
3 4 5 6
Expand Down Expand Up @@ -40,7 +41,7 @@ end
@test index(set(s, Dim{:row}([:x, :y, :z])), :row) == [:x, :y, :z]
end

@testset "DimArray dim Dimension" begin
@testset "DimArray Dimension" begin
@test typeof(dims(set(da, X=:a, Y=:b))) <: Tuple{<:Dim{:a},<:Dim{:b}}
@test typeof(dims(set(da2, Dim{:row}(Y()), Dim{:column}(X())))) <: Tuple{<:Y,<:X}
@test typeof(dims(set(da, X => Ti(), Y => Z()))) <: Tuple{<:Ti,<:Z}
Expand All @@ -60,6 +61,14 @@ end
end

@testset "dim lookup" begin

@test lookup(set(dims(da2), NoLookup())) ==
(NoLookup(Base.OneTo(3)), NoLookup(Base.OneTo(4)))
@test lookup(set(da2, NoLookup())) ==
(NoLookup(Base.OneTo(3)), NoLookup(Base.OneTo(4)))
@test lookup(set(da2, Categorical)) ==
(Categorical(10.0:10.0:30.0, ForwardOrdered(), NoMetadata()),
Categorical(-2.0:1.0:1.0, ForwardOrdered(), NoMetadata()))
@test lookup(set(da2, :column => NoLookup(), :row => Sampled(sampling=Intervals(Center())))) ==
(Sampled(10.0:10.0:30.0, ForwardOrdered(), Regular(10.0), Intervals(Center()), NoMetadata()), NoLookup(Base.OneTo(4)))
@test lookup(set(da2, column=NoLookup())) ==
Expand All @@ -73,14 +82,18 @@ end
@test metadata(cat_da_m) == Dict()

@testset "span" begin
@test span(set(da2, Irregular)) ==
(Irregular((10.0, 30.0)), Irregular((-2.0, 1.0)))
@test span(set(da2, Regular)) == (Regular(10.0), Regular(1.0))
# TODO: should this error? the span step doesn't match the index step
@test span(set(da2, row=Irregular(10, 12), column=Regular(9.9))) ==
(Irregular(10, 12), Regular(9.9))
@test _set(Sampled(), AutoSpan()) == Sampled()
@test _set(Sampled(), Irregular()) == Sampled(; span= Irregular())
@test set(Sampled(), AutoSpan()) == Sampled()
@test set(Sampled(), Irregular()) == Sampled(; span=Irregular())
@test set(Sampled(), Regular()) == Sampled(; span=Regular())
@test set(Sampled(1:2:10), Regular()) == Sampled(1:2:10; span=Regular(2))
end

interval_da = set(da, X=Intervals(), Y=Intervals())
@testset "locus" begin
@test_throws ArgumentError set(da2, (End(), Center()))
@test locus(set(interval_da, X(End()), Y(Center()))) == (End(), Center())
Expand All @@ -99,8 +112,8 @@ end
@test sampling(interval_da) == (Intervals(Center()), Intervals(Center()))
@test sampling(set(da, (X(Intervals(End())), Y(Intervals(Start()))))) ==
(Intervals(End()), Intervals(Start()))
@test _set(Sampled(), AutoSampling()) == Sampled()
@test _set(Sampled(), Intervals()) == Sampled(; sampling=Intervals())
@test set(Sampled(), AutoSampling()) == Sampled()
@test set(Sampled(), Intervals) == Sampled(; sampling=Intervals())
@test _set(Points(), AutoSampling()) == Points()
@test _set(AutoSampling(), Intervals()) == Intervals()
@test _set(AutoSampling(), AutoSampling()) == AutoSampling()
Expand Down Expand Up @@ -152,11 +165,8 @@ end
end

@testset "errors with set" begin
@test_throws ArgumentError set(da, Sampled())
@test_throws ArgumentError set(s, Categorical())
@test_throws ArgumentError set(da, Irregular())
@test_throws ArgumentError set(da, X=7)
@test_throws ArgumentError _set(dims(da, X), X(7))
@test_throws ArgumentError set(dims(da, X), X(7))
@test_throws ArgumentError set(da, notadimname=Sampled())
end

Expand Down

0 comments on commit d7ae55b

Please sign in to comment.