Skip to content

Commit 12aad27

Browse files
author
Chris Foster
committed
Access to the values of an axis by name using getproperty
This is particularly useful and succinct when you're working on domain specific data with known axis names.
1 parent 365496c commit 12aad27

File tree

3 files changed

+35
-2
lines changed

3 files changed

+35
-2
lines changed

docs/src/index.md

+15-2
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,21 @@ And data, a 2400001×2 Array{Float64,2}:
7979
8080
```
8181

82-
AxisArrays behave like regular arrays, but they additionally use the axis
83-
information to enable all sorts of fancy behaviors. For example, we can specify
82+
AxisArrays behave like regular arrays, but they carry extra information about
83+
their axes along with them:
84+
85+
```jldoctest
86+
julia> A.time
87+
0.0 s:2.5e-5 s:60.0 s
88+
89+
julia> A.chan
90+
2-element Array{Symbol,1}:
91+
:c1
92+
:c2
93+
94+
```
95+
96+
This enables all sorts of fancy indexing behaviors. For example, we can specify
8497
indices in *any* order, just so long as we annotate them with the axis name:
8598

8699
```jldoctest

src/core.jl

+12
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,18 @@ function axisdim(::Type{AxisArray{T,N,D,Ax}}, ::Type{<:Axis{name,S} where S}) wh
285285
idx
286286
end
287287

288+
# Access to the values of axes by name
289+
function Base.getproperty(A::AxisArray, name::Symbol)
290+
if name === :data || name === :axes
291+
getfield(A, name)
292+
else
293+
# Other things are axis names
294+
getfield(A, :axes)[axisdim(A, Axis{name})].val
295+
end
296+
end
297+
# Expose only axis names to tab completion
298+
Base.propertynames(A::AxisArray) = axisnames(A)
299+
288300
# Base definitions that aren't provided by AbstractArray
289301
@inline Base.size(A::AxisArray) = size(A.data)
290302
@inline Base.size(A::AxisArray, Ax::Axis) = size(A.data, axisdim(A, Ax))

test/core.jl

+8
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,14 @@ A = @inferred(AxisArray(reshape(1:24, 2,3,4),
167167
@test axisdim(A, Axis{:x}) == axisdim(A, Axis{:x}()) == 1
168168
@test axisdim(A, Axis{:y}) == axisdim(A, Axis{:y}()) == 2
169169
@test axisdim(A, Axis{:z}) == axisdim(A, Axis{:z}()) == 3
170+
# Test that getproperty is fully inferred when a const name is supplied
171+
let getx(A) = A.x,
172+
getz(A) = A.z
173+
@test @inferred(getx(A)) == A.axes[1].val
174+
@test @inferred(getz(A)) == A.axes[3].val
175+
end
176+
@test propertynames(A) == (:x, :y, :z)
177+
170178
# Test axes
171179
@test @inferred(AxisArrays.axes(A)) == (Axis{:x}(.1:.1:.2), Axis{:y}(1//10:1//10:3//10), Axis{:z}(["a", "b", "c", "d"]))
172180
@test @inferred(AxisArrays.axes(A, Axis{:x})) == @inferred(AxisArrays.axes(A, Axis{:x}())) == Axis{:x}(.1:.1:.2)

0 commit comments

Comments
 (0)