Skip to content

Commit 8cb003b

Browse files
Evizerombauman
authored andcommitted
Towards 0.7 support (#143)
* work towards 0.7 support * Use Val() syntax in tests * Type stable constructors * lastindex, range, and squeeze deprecations... the squeeze deprecation will need some more work to be type-stable using a varargs kwarg * Core tests pass! * fixup * Try using a tuple of AxisArrays as "axes"-ish objects from reduced_indices * fixup * Minor ntuple and axes/indices fixes * update travis yml * drop 0.6 support * fix more deprecation warnings * More qualifications of axes * Replace _nextaxistype with _default_axis * Make default_axes support different numbers of axes, move errors into AxisArray constructor. Simplify make_axes_match. * Indexing fixes: * More axes qualifiers * Fixup an earlier findall replacement * Simplify reaxis and explicitly implement linear indexing there * fixup * Indexing tests pass! * Fix SortedVector tests (random seeding has changed) * Same deal with categorical vectors * find->findall, axes qualification * Combine and join fixes * Disable problematic inference failures * final fixes for v"1.0" * Try deploying with 1.0; add Unitful for the example * Add a notice regarding the `axes` function to the README * Test and fix String(::IOBuffer) deprecation * Re-enable ambiguity tests on 1.0 * Re-enable disabled tests - just don't test at-inferred
1 parent 2c40730 commit 8cb003b

19 files changed

+325
-242
lines changed

.travis.yml

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,30 @@ os:
33
- linux
44
- osx
55
julia:
6-
- 0.6
6+
- 0.7
7+
- 1.0
78
- nightly
89
notifications:
910
email: false
1011
matrix:
1112
allow_failures:
12-
- julia: nightly
13+
- julia: nightly
14+
1315
# uncomment the following lines to override the default test script
1416
script:
1517
- if [[ -a .git/shallow ]]; then git fetch --unshallow; fi
16-
- julia --check-bounds=yes -e 'Pkg.clone(pwd()); Pkg.build("AxisArrays"); Pkg.test("AxisArrays"; coverage=true)'
18+
- julia --check-bounds=yes --color=yes -e 'import Pkg; Pkg.clone(pwd()); Pkg.build("AxisArrays"); Pkg.test("AxisArrays"; coverage=true)';
19+
20+
jobs:
21+
include:
22+
- stage: deploy
23+
julia: 0.7
24+
os: linux
25+
script:
26+
- julia -e 'import Pkg; Pkg.clone(pwd()); Pkg.build("AxisArrays")'
27+
- julia -e 'import Pkg; Pkg.add("Documenter"); Pkg.add("Unitful")'
28+
- julia -e 'import AxisArrays; ENV["DOCUMENTER_DEBUG"] = "true"; include(joinpath("docs","make.jl"))'
29+
1730
after_success:
18-
- julia -e 'Pkg.add("Unitful")'
19-
- julia -e 'cd(Pkg.dir("AxisArrays")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(Coveralls.process_folder())'
20-
- julia -e 'Pkg.add("Documenter")'
21-
- julia -e 'cd(Pkg.dir("AxisArrays")); include(joinpath("docs", "make.jl"))'
31+
# - julia -e 'Pkg.add("Unitful")' ?
32+
- julia -e 'using Pkg; Pkg.add("Coverage"); using Coverage; Coveralls.submit(process_folder())'

README.md

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,31 @@ In contrast to similar approaches in [Images.jl](https://github.com/timholy/Imag
1010

1111
Collaboration is welcome! This is still a work-in-progress. See [the roadmap](https://github.com/JuliaArrays/AxisArrays.jl/issues/7) for the project's current direction.
1212

13+
### Notice regarding `axes`
14+
15+
Since Julia version 0.7, the name `axes` is exported by default from `Base`
16+
with a meaning (and behavior) that is distinct from how AxisArrays has been
17+
using it. Since you cannot simultaneously be `using` the same name from the two
18+
different modules, Julia will issue a warning, and it'll error if you try to
19+
use `axes` without qualification:
20+
21+
```julia
22+
julia> axes([])
23+
WARNING: both AxisArrays and Base export "axes"; uses of it in module Main must be qualified
24+
ERROR: UndefVarError: axes not defined
25+
```
26+
27+
Packages that are upgrading to support 0.7+ and use AxisArrays should follow
28+
this upgrade path:
29+
30+
* Replace all uses of the `axes` function with the fully-qualified `AxisArrays.axes`
31+
* Replace all uses of the deprecated `indices` function with the un-qualified `axes`
32+
* Immediately after `using AxisArrays`, add `const axes = Base.axes`
33+
34+
In the future, AxisArrays will be looking for a new name for its functionality.
35+
This will allow you to use the idiomatic `Base` name and offers an easy upgrade
36+
path to whatever the new name will be.
37+
1338
## Example of currently-implemented behavior:
1439

1540
```julia
@@ -97,7 +122,7 @@ And data, a 7-element Array{Float64,1}:
97122
-0.226449
98123
0.821446
99124

100-
julia> axes(ans, 1)
125+
julia> AxisArrays.axes(ans, 1)
101126
AxisArrays.Axis{:time,StepRangeLen{Quantity{Float64, Dimensions:{𝐓}, Units:{s}},Base.TwicePrecision{Quantity{Float64, Dimensions:{𝐓}, Units:{s}}},Base.TwicePrecision{Quantity{Float64, Dimensions:{𝐓}, Units:{s}}}}}(5.0e-5 s:2.5e-5 s:0.0002 s)
102127
```
103128

@@ -154,7 +179,7 @@ very powerful behaviors. For example, let's threshold our data and find windows
154179
about those threshold crossings.
155180

156181
```julia
157-
julia> idxs = find(diff(A[:,:c1] .< -15) .> 0);
182+
julia> idxs = findall(diff(A[:,:c1] .< -15) .> 0);
158183

159184
julia> spks = A[atindex(-200µs .. 800µs, idxs), :c1]
160185
2-dimensional AxisArray{Float64,2,...} with axes:

REQUIRE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
julia 0.6
1+
julia 0.7
22
IntervalSets 0.1
33
IterTools
44
RangeArrays

docs/make.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ makedocs(
77
deploydocs(
88
deps = Deps.pip("mkdocs", "python-markdown-math"),
99
repo = "github.com/JuliaArrays/AxisArrays.jl.git",
10-
julia = "0.6"
10+
julia = "1.0"
1111
)

docs/src/index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ And data, a 7-element Array{Float64,1}:
121121
-0.226449
122122
0.821446
123123
124-
julia> axes(ans, 1)
124+
julia> AxisArrays.axes(ans, 1)
125125
AxisArrays.Axis{:time,StepRangeLen{Quantity{Float64, Dimensions:{𝐓}, Units:{s}},Base.TwicePrecision{Quantity{Float64, Dimensions:{𝐓}, Units:{s}}},Base.TwicePrecision{Quantity{Float64, Dimensions:{𝐓}, Units:{s}}}}}(5.0e-5 s:2.5e-5 s:0.0002 s)
126126
127127
```
@@ -182,7 +182,7 @@ very powerful behaviors. For example, let's threshold our data and find windows
182182
about those threshold crossings.
183183

184184
```jldoctest
185-
julia> idxs = find(diff(A[:,:c1] .< -15) .> 0);
185+
julia> idxs = findall(diff(A[:,:c1] .< -15) .> 0);
186186
187187
julia> spks = A[atindex(-200µs .. 800µs, idxs), :c1]
188188
2-dimensional AxisArray{Float64,2,...} with axes:

src/AxisArrays.jl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
__precompile__()
1+
VERSION < v"0.7.0-beta2.199" && __precompile__()
22

33
module AxisArrays
44

@@ -7,8 +7,9 @@ import Base.Iterators: repeated
77
using RangeArrays, IntervalSets
88
using IterTools
99
using Compat
10-
using Compat.Dates
11-
using Compat: AbstractRange
10+
using Dates
11+
12+
function axes end
1213

1314
export AxisArray, Axis, axisnames, axisvalues, axisdim, axes, atindex, atvalue, collapse
1415

src/categoricalvector.jl

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,13 @@ struct CategoricalVector{T, A<:AbstractVector{T}} <: AbstractVector{T}
4343
data::A
4444
end
4545

46-
function CategoricalVector(data::AbstractVector{T}) where T
47-
CategoricalVector{T, typeof(data)}(data)
48-
end
49-
5046
Base.getindex(v::CategoricalVector, idx::Int) = v.data[idx]
5147
Base.getindex(v::CategoricalVector, idx::AbstractVector) = CategoricalVector(v.data[idx])
5248

5349
Base.length(v::CategoricalVector) = length(v.data)
5450
Base.size(v::CategoricalVector) = size(v.data)
5551
Base.size(v::CategoricalVector, i) = size(v.data, i)
56-
Base.indices(v::CategoricalVector) = indices(v.data)
52+
Base.axes(v::CategoricalVector) = Base.axes(v.data)
5753

5854
axistrait(::Type{CategoricalVector{T,A}}) where {T,A} = Categorical
5955
checkaxis(::CategoricalVector) = nothing
@@ -65,7 +61,7 @@ checkaxis(::CategoricalVector) = nothing
6561
axisindexes(ax::Axis{S,CategoricalVector{T,A}}, idx) where {T<:Tuple,S,A} = axisindexes(ax, (idx,))
6662

6763
function axisindexes(ax::Axis{S,CategoricalVector{T,A}}, idx::Tuple) where {T<:Tuple,S,A}
68-
collect(filter(ax_idx->_tuple_matches(ax.val[ax_idx], idx), indices(ax.val)...))
64+
collect(filter(ax_idx->_tuple_matches(ax.val[ax_idx], idx), Base.axes(ax.val)...))
6965
end
7066

7167
function _tuple_matches(element::Tuple, idx::Tuple)

src/combine.jl

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,24 @@ function equalvalued(X::NTuple)
99
return allequal
1010
end #equalvalued
1111

12-
sizes(As::T...) where {T<:AxisArray} = tuple(zip(map(a -> map(length, indices(a)), As)...)...)
13-
matchingdims(As::NTuple{N,T}) where {N,T<:AxisArray} = all(equalvalued, sizes(As...))
14-
matchingdimsexcept(As::NTuple{N,T}, n::Int) where {N,T<:AxisArray} = all(equalvalued, sizes(As...)[[1:n-1; n+1:end]])
12+
sizes(As::AxisArray...) = tuple(zip(map(a -> map(length, Base.axes(a)), As)...)...)
13+
matchingdims(As::Tuple{Vararg{AxisArray}}) = all(equalvalued, sizes(As...))
14+
matchingdimsexcept(As::Tuple{Vararg{AxisArray}}, n::Int) = all(equalvalued, sizes(As...)[[1:n-1; n+1:end]])
1515

16-
function Base.cat(n::Integer, As::AxisArray{T}...) where T
16+
Base.cat(As::AxisArray{T}...; dims) where {T} = _cat(dims, As...)
17+
_cat(::Val{n}, As...) where {n} = _cat(n, As...)
18+
19+
@inline function _cat(n::Integer, As...)
1720
if n <= ndims(As[1])
1821
matchingdimsexcept(As, n) || error("All non-concatenated axes must be identically-valued")
1922
newaxis = Axis{axisnames(As[1])[n]}(vcat(map(A -> A.axes[n].val, As)...))
2023
checkaxis(newaxis)
21-
return AxisArray(cat(n, map(A->A.data, As)...), (As[1].axes[1:n-1]..., newaxis, As[1].axes[n+1:end]...))
24+
return AxisArray(cat(map(A->A.data, As)..., dims=n), (As[1].axes[1:n-1]..., newaxis, As[1].axes[n+1:end]...))
2225
else
2326
matchingdims(As) || error("All axes must be identically-valued")
24-
return AxisArray(cat(n, map(A->A.data, As)...), As[1].axes)
27+
return AxisArray(cat(map(A->A.data, As)..., dims=n), As[1].axes)
2528
end #if
26-
end #Base.cat
29+
end
2730

2831
function axismerge(method::Symbol, axes::Axis{name,T}...) where {name,T}
2932

@@ -122,7 +125,7 @@ Combines AxisArrays with matching axis names into a single AxisArray. Unlike `me
122125
If an array value in the output array is not defined in any of the input arrays (i.e. in the case of a left, right, or outer join), it takes the value of the optional `fillvalue` keyword argument (default zero).
123126
"""
124127
function Base.join(As::AxisArray{T,N,D,Ax}...; fillvalue::T=zero(T),
125-
newaxis::Axis=_nextaxistype(As[1].axes)(1:length(As)),
128+
newaxis::Axis=_default_axis(1:length(As), ndims(As[1])+1),
126129
method::Symbol=:outer) where {T,N,D,Ax}
127130

128131
prejoin_resultaxes = map(as -> axismerge(method, as...), map(tuple, axes.(As)...))
@@ -141,7 +144,7 @@ function Base.join(As::AxisArray{T,N,D,Ax}...; fillvalue::T=zero(T),
141144
end #join
142145

143146
function _collapse_array_axes(array_name, array_axes...)
144-
((array_name, (idx isa Tuple ? idx : (idx,))...) for idx in product((Ax.val for Ax in array_axes)...))
147+
((array_name, (idx isa Tuple ? idx : (idx,))...) for idx in Iterators.product((Ax.val for Ax in array_axes)...))
145148
end
146149

147150
function _collapse_axes(array_names, array_axes)
@@ -150,12 +153,12 @@ function _collapse_axes(array_names, array_axes)
150153
end))
151154
end
152155

153-
function _splitall(::Type{Val{N}}, As...) where N
154-
tuple((Base.IteratorsMD.split(A, Val{N}) for A in As)...)
156+
function _splitall(::Val{N}, As...) where N
157+
tuple((Base.IteratorsMD.split(A, Val(N)) for A in As)...)
155158
end
156159

157-
function _reshapeall(::Type{Val{N}}, As...) where N
158-
tuple((reshape(A, Val{N}) for A in As)...)
160+
function _reshapeall(::Val{N}, As...) where N
161+
tuple((reshape(A, Val(N)) for A in As)...)
159162
end
160163

161164
function _check_common_axes(common_axis_tuple)
@@ -174,36 +177,36 @@ function _collapsed_axis_eltype(LType, trailing_axes)
174177
return typejoin(eltypes...)
175178
end
176179

177-
function collapse(::Type{Val{N}}, As::Vararg{AxisArray, AN}) where {N, AN}
178-
collapse(Val{N}, ntuple(identity, Val{AN}), As...)
180+
function collapse(::Val{N}, As::Vararg{AxisArray, AN}) where {N, AN}
181+
collapse(Val(N), ntuple(identity, AN), As...)
179182
end
180183

181-
function collapse(::Type{Val{N}}, ::Type{NewArrayType}, As::Vararg{AxisArray, AN}) where {N, AN, NewArrayType<:AbstractArray}
182-
collapse(Val{N}, NewArrayType, ntuple(identity, Val{AN}), As...)
184+
function collapse(::Val{N}, ::Type{NewArrayType}, As::Vararg{AxisArray, AN}) where {N, AN, NewArrayType<:AbstractArray}
185+
collapse(Val(N), NewArrayType, ntuple(identity, AN), As...)
183186
end
184187

185-
@generated function collapse(::Type{Val{N}}, labels::NTuple{AN, LType}, As::Vararg{AxisArray, AN}) where {N, AN, LType}
188+
@generated function collapse(::Val{N}, labels::NTuple{AN, LType}, As::Vararg{AxisArray, AN}) where {N, AN, LType}
186189
collapsed_dim_int = Int(N) + 1
187190
new_eltype = Base.promote_eltype(As...)
188191

189192
quote
190-
collapse(Val{N}, Array{$new_eltype, $collapsed_dim_int}, labels, As...)
193+
collapse(Val(N), Array{$new_eltype, $collapsed_dim_int}, labels, As...)
191194
end
192195
end
193196

194197
"""
195-
collapse(::Type{Val{N}}, As::AxisArray...) -> AxisArray
196-
collapse(::Type{Val{N}}, labels::Tuple, As::AxisArray...) -> AxisArray
197-
collapse(::Type{Val{N}}, ::Type{NewArrayType}, As::AxisArray...) -> AxisArray
198-
collapse(::Type{Val{N}}, ::Type{NewArrayType}, labels::Tuple, As::AxisArray...) -> AxisArray
198+
collapse(::Val{N}, As::AxisArray...) -> AxisArray
199+
collapse(::Val{N}, labels::Tuple, As::AxisArray...) -> AxisArray
200+
collapse(::Val{N}, ::Type{NewArrayType}, As::AxisArray...) -> AxisArray
201+
collapse(::Val{N}, ::Type{NewArrayType}, labels::Tuple, As::AxisArray...) -> AxisArray
199202
200203
Collapses `AxisArray`s with `N` equal leading axes into a single `AxisArray`.
201204
All additional axes in any of the arrays are collapsed into a single additional
202205
axis of type `Axis{:collapsed, CategoricalVector{Tuple}}`.
203206
204207
### Arguments
205208
206-
* `::Type{Val{N}}`: the greatest common dimension to share between all input
209+
* `::Val{N}`: the greatest common dimension to share between all input
207210
arrays. The remaining axes are collapsed. All `N` axes must be common
208211
to each input array, at the same dimension. Values from `0` up to the
209212
minimum number of dimensions across all input arrays are allowed.
@@ -247,7 +250,7 @@ And data, a 10×2 Array{Float64,2}:
247250
0.650277 0.135061
248251
0.688773 0.513845
249252
250-
julia> collapsed = collapse(Val{1}, (:price, :size), price_data, size_data)
253+
julia> collapsed = collapse(Val(1), (:price, :size), price_data, size_data)
251254
2-dimensional AxisArray{Float64,2,...} with axes:
252255
:time, 2016-01-01:1 day:2016-01-10
253256
:collapsed, Tuple{Symbol,Vararg{Symbol,N} where N}[(:price,), (:size, :area), (:size, :volume)]
@@ -268,7 +271,7 @@ true
268271
```
269272
270273
"""
271-
@generated function collapse(::Type{Val{N}},
274+
@generated function collapse(::Val{N},
272275
::Type{NewArrayType},
273276
labels::NTuple{AN, LType},
274277
As::Vararg{AxisArray, AN}) where {N, AN, LType, NewArrayType<:AbstractArray}
@@ -285,10 +288,10 @@ true
285288
))
286289
end
287290

288-
collapsed_dim = Val{N + 1}
291+
collapsed_dim = Val(N + 1)
289292
collapsed_dim_int = Int(N) + 1
290293

291-
common_axes, trailing_axes = zip(_splitall(Val{N}, axisparams.(As)...)...)
294+
common_axes, trailing_axes = zip(_splitall(Val(N), axisparams.(As)...)...)
292295

293296
foreach(_check_common_axes, zip(common_axes...))
294297

@@ -300,7 +303,7 @@ true
300303
new_eltype = Base.promote_eltype(As...)
301304

302305
quote
303-
common_axes, trailing_axes = zip(_splitall(Val{N}, axes.(As)...)...)
306+
common_axes, trailing_axes = zip(_splitall(Val(N), axes.(As)...)...)
304307

305308
for common_axis_tuple in zip(common_axes...)
306309
if !isempty(common_axis_tuple)
@@ -316,7 +319,7 @@ true
316319
end
317320
end
318321

319-
array_data = cat($collapsed_dim, _reshapeall($collapsed_dim, As...)...)
322+
array_data = cat(_reshapeall($collapsed_dim, As...)..., dims=$collapsed_dim)
320323

321324
axis_array_type = AxisArray{
322325
$new_eltype,

0 commit comments

Comments
 (0)