Skip to content

Commit d7ae55b

Browse files
authored
Merge 1b6f600 into 2a11716
2 parents 2a11716 + 1b6f600 commit d7ae55b

File tree

5 files changed

+69
-19
lines changed

5 files changed

+69
-19
lines changed

src/Dimensions/set.jl

+4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
const DimSetters = Union{LookupSetters,Type,UnionAll,Dimension,Symbol}
22

3+
set(dim::Dimension, ::Type{T}) where T = set(dim, T())
4+
set(dims::DimTuple, ::Type{T}) where T = set(dims, T())
35
set(dim::Dimension, x::DimSetters) = _set(dim, x)
46
set(dims_::DimTuple, args::Union{Dimension,DimTuple,Pair}...; kw...) =
57
_set(dims_, args...; kw...)
8+
set(dims::DimTuple, l::Lookup) = set(dims, map(d -> basedims(d) => l, dims)...)
9+
set(dims::DimTuple, l::LookupTrait) = set(dims, map(d -> basedims(d) => l, dims)...)
610
# Convert args/kw to dims and set
711
_set(dims_::DimTuple, args::Dimension...; kw...) = _set(dims_, (args..., kw2dims(kw)...))
812
# Convert pairs to wrapped dims and set

src/Lookups/lookup_traits.jl

+2
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,8 @@ struct AutoStep end
216216
struct AutoBounds end
217217
struct AutoDim end
218218

219+
Base.step(::AutoSpan) = AutoStep()
220+
219221
"""
220222
Regular <: Span
221223

src/Lookups/set.jl

+22
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
const LookupSetters = Union{AllMetadata,Lookup,LookupTrait,Nothing,AbstractArray}
2+
23
set(lookup::Lookup, x::LookupSetters) = _set(lookup, x)
4+
set(lookup::Lookup, ::Type{T}) where T = _set(lookup, T())
35

46
# _set(lookup::Lookup, newlookup::Lookup) = lookup
57
_set(lookup::AbstractCategorical, newlookup::AutoLookup) = begin
@@ -62,6 +64,26 @@ _set(order::Order, neworder::Order) = neworder
6264
_set(order::Order, neworder::AutoOrder) = order
6365

6466
# Span
67+
_set(lookup::AbstractSampled, ::Irregular{AutoBounds}) = begin
68+
bnds = if parent(lookup) isa AutoValues || span(lookup) isa AutoSpan
69+
AutoBounds()
70+
else
71+
bounds(lookup)
72+
end
73+
rebuild(lookup; span=Irregular(bnds))
74+
end
75+
_set(lookup::AbstractSampled, ::Regular{AutoStep}) = begin
76+
stp = if span(lookup) isa AutoSpan || step(lookup) isa AutoStep
77+
if parent(lookup) isa AbstractRange
78+
step(parent(lookup))
79+
else
80+
AutoStep()
81+
end
82+
else
83+
step(lookup)
84+
end
85+
rebuild(lookup; span=Regular(stp))
86+
end
6587
_set(lookup::AbstractSampled, span::Span) = rebuild(lookup; span=span)
6688
_set(lookup::AbstractSampled, span::AutoSpan) = lookup
6789
_set(span::Span, newspan::Span) = newspan

src/set.jl

+21-9
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ of a [`Lookup`](@ref) to `set` - there is no ambiguity.
2020
To set fields of a `Lookup` you need to specify the dimension. This can be done
2121
using `X => val` pairs, `X = val` keyword arguments, or `X(val)` wrapped arguments.
2222
23+
You can also set the fields of all dimensions by simply passing a single [`Lookup`](@ref)
24+
or lookup trait - it will be set for all dimensions.
25+
2326
When a `Dimension` or `Lookup` is passed to `set` to replace the
2427
existing ones, fields that are not set will keep their original values.
2528
@@ -114,27 +117,36 @@ julia> set(da, :custom => DD.Irregular(10, 12), Z => DD.Regular(9.9))
114117
```
115118
"""
116119
function set end
117-
set(A::DimArrayOrStack, x::T) where {T<:Union{Lookup,LookupTrait}} = _onlydimerror(x)
118-
set(x::DimArrayOrStack, ::Type{T}) where T = set(x, T())
120+
# Types are constructed
121+
Base.@assume_effects :effect_free set(x::DimArrayOrStack, ::Type{T}) where T = set(x, T())
119122

120-
set(A::AbstractDimStack, x::Lookup) = Lookups._cantseterror(A, x)
121-
set(A::AbstractDimArray, x::Lookup) = Lookups._cantseterror(A, x)
122-
set(A, x) = Lookups._cantseterror(A, x)
123-
set(A::DimArrayOrStack, args::Union{Dimension,DimTuple,Pair}...; kw...) =
123+
# Dimensions and pairs are set for dimensions
124+
Base.@assume_effects :effect_free set(A::DimArrayOrStack, args::Union{Dimension,DimTuple,Pair}...; kw...) =
124125
rebuild(A, data(A), set(dims(A), args...; kw...))
125-
set(A::AbstractDimArray, newdata::AbstractArray) = begin
126+
# Single traits are set for all dimensions
127+
Base.@assume_effects :effect_free set(A::DimArrayOrStack, x::LookupTrait) =
128+
set(A, map(d -> basedims(d) => x, dims(A))...)
129+
# Single lookups are set for all dimensions
130+
Base.@assume_effects :effect_free set(A::AbstractDimArray, x::Lookup) =
131+
set(A, map(d -> basedims(d) => x, dims(A))...)
132+
Base.@assume_effects :effect_free set(A::AbstractDimStack, x::Lookup) =
133+
set(A, map(d -> basedims(d) => x, dims(A))...)
134+
# Arrays are set as data for AbstractDimArray
135+
Base.@assume_effects :effect_free set(A::AbstractDimArray, newdata::AbstractArray) = begin
126136
axes(A) == axes(newdata) || _axiserr(A, newdata)
127137
rebuild(A; data=newdata)
128138
end
129-
set(s::AbstractDimStack, newdata::NamedTuple) = begin
139+
# NamedTuples are set as data for AbstractDimStack
140+
Base.@assume_effects :effect_free set(s::AbstractDimStack, newdata::NamedTuple) = begin
130141
dat = data(s)
131142
keys(dat) === keys(newdata) || _keyerr(keys(dat), keys(newdata))
132143
map(dat, newdata) do d, nd
133144
axes(d) == axes(nd) || _axiserr(d, nd)
134145
end
135146
rebuild(s; data=newdata)
136147
end
148+
# Other things error
149+
Base.@assume_effects :effect_free set(A, x) = Lookups._cantseterror(A, x)
137150

138-
@noinline _onlydimerror(x) = throw(ArgumentError("Can only set $(typeof(x)) for a dimension. Specify which dimension you mean with `X => property`"))
139151
@noinline _axiserr(a, b) = throw(ArgumentError("passed in axes $(axes(b)) do not match the currect axes $(axes(a))"))
140152
@noinline _keyerr(ka, kb) = throw(ArgumentError("keys $ka and $kb do not match"))

test/set.jl

+20-10
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ a = [1 2; 3 4]
77
dimz = (X(143.0:2.0:145.0; lookup=Sampled(order=ForwardOrdered()), metadata=Metadata(Dict(:meta => "X"))),
88
Y(-38.0:2.0:-36.0; lookup=Sampled(order=ForwardOrdered()), metadata=Metadata(Dict(:meta => "Y"))))
99
da = DimArray(a, dimz; name=:test)
10+
interval_da = set(da, X=Intervals(), Y=Intervals())
1011

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

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

6263
@testset "dim lookup" begin
64+
65+
@test lookup(set(dims(da2), NoLookup())) ==
66+
(NoLookup(Base.OneTo(3)), NoLookup(Base.OneTo(4)))
67+
@test lookup(set(da2, NoLookup())) ==
68+
(NoLookup(Base.OneTo(3)), NoLookup(Base.OneTo(4)))
69+
@test lookup(set(da2, Categorical)) ==
70+
(Categorical(10.0:10.0:30.0, ForwardOrdered(), NoMetadata()),
71+
Categorical(-2.0:1.0:1.0, ForwardOrdered(), NoMetadata()))
6372
@test lookup(set(da2, :column => NoLookup(), :row => Sampled(sampling=Intervals(Center())))) ==
6473
(Sampled(10.0:10.0:30.0, ForwardOrdered(), Regular(10.0), Intervals(Center()), NoMetadata()), NoLookup(Base.OneTo(4)))
6574
@test lookup(set(da2, column=NoLookup())) ==
@@ -73,14 +82,18 @@ end
7382
@test metadata(cat_da_m) == Dict()
7483

7584
@testset "span" begin
85+
@test span(set(da2, Irregular)) ==
86+
(Irregular((10.0, 30.0)), Irregular((-2.0, 1.0)))
87+
@test span(set(da2, Regular)) == (Regular(10.0), Regular(1.0))
7688
# TODO: should this error? the span step doesn't match the index step
7789
@test span(set(da2, row=Irregular(10, 12), column=Regular(9.9))) ==
7890
(Irregular(10, 12), Regular(9.9))
79-
@test _set(Sampled(), AutoSpan()) == Sampled()
80-
@test _set(Sampled(), Irregular()) == Sampled(; span= Irregular())
91+
@test set(Sampled(), AutoSpan()) == Sampled()
92+
@test set(Sampled(), Irregular()) == Sampled(; span=Irregular())
93+
@test set(Sampled(), Regular()) == Sampled(; span=Regular())
94+
@test set(Sampled(1:2:10), Regular()) == Sampled(1:2:10; span=Regular(2))
8195
end
8296

83-
interval_da = set(da, X=Intervals(), Y=Intervals())
8497
@testset "locus" begin
8598
@test_throws ArgumentError set(da2, (End(), Center()))
8699
@test locus(set(interval_da, X(End()), Y(Center()))) == (End(), Center())
@@ -99,8 +112,8 @@ end
99112
@test sampling(interval_da) == (Intervals(Center()), Intervals(Center()))
100113
@test sampling(set(da, (X(Intervals(End())), Y(Intervals(Start()))))) ==
101114
(Intervals(End()), Intervals(Start()))
102-
@test _set(Sampled(), AutoSampling()) == Sampled()
103-
@test _set(Sampled(), Intervals()) == Sampled(; sampling=Intervals())
115+
@test set(Sampled(), AutoSampling()) == Sampled()
116+
@test set(Sampled(), Intervals) == Sampled(; sampling=Intervals())
104117
@test _set(Points(), AutoSampling()) == Points()
105118
@test _set(AutoSampling(), Intervals()) == Intervals()
106119
@test _set(AutoSampling(), AutoSampling()) == AutoSampling()
@@ -152,11 +165,8 @@ end
152165
end
153166

154167
@testset "errors with set" begin
155-
@test_throws ArgumentError set(da, Sampled())
156-
@test_throws ArgumentError set(s, Categorical())
157-
@test_throws ArgumentError set(da, Irregular())
158168
@test_throws ArgumentError set(da, X=7)
159-
@test_throws ArgumentError _set(dims(da, X), X(7))
169+
@test_throws ArgumentError set(dims(da, X), X(7))
160170
@test_throws ArgumentError set(da, notadimname=Sampled())
161171
end
162172

0 commit comments

Comments
 (0)