-
Notifications
You must be signed in to change notification settings - Fork 41
/
lookup_traits.jl
285 lines (201 loc) · 6.49 KB
/
lookup_traits.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
"""
LookupTrait
Abstract supertype of all traits of a [`Lookup`](@ref).
These modify the behaviour of the lookup index.
The term "Trait" is used loosely - these may be fields of an object
of traits hard-coded to specific types.
"""
abstract type LookupTrait end
"""
Order <: LookupTrait
Traits for the order of a [`Lookup`](@ref). These determine how
`searchsorted` finds values in the index, and how objects are plotted.
"""
abstract type Order <: LookupTrait end
"""
Ordered <: Order
Supertype for the order of an ordered [`Lookup`](@ref),
including [`ForwardOrdered`](@ref) and [`ReverseOrdered`](@ref).
"""
abstract type Ordered <: Order end
"""
AutoOrder <: Order
AutoOrder()
Specifies that the `Order` of a `Lookup` will be found automatically
where possible.
"""
struct AutoOrder <: Order end
"""
ForwardOrdered <: Ordered
ForwardOrdered()
Indicates that the `Lookup` index is in the normal forward order.
"""
struct ForwardOrdered <: Ordered end
"""
ReverseOrdered <: Ordered
ReverseOrdered()
Indicates that the `Lookup` index is in the reverse order.
"""
struct ReverseOrdered <: Ordered end
"""
Unordered <: Order
Unordered()
Indicates that `Lookup` is unordered.
This means the index cannot be searched with `searchsortedfirst`
or similar optimised methods - instead it will use `findfirst`.
"""
struct Unordered <: Order end
isrev(x) = isrev(typeof(x))
isrev(::Type{<:ForwardOrdered}) = false
isrev(::Type{<:ReverseOrdered}) = true
"""
Position <: LookupTrait
Abstract supertype of types that indicate the locus of index values
where they represent [`Intervals`](@ref).
These allow for values array cells to align with the [`Start`](@ref),
[`Center`](@ref), or [`End`](@ref) of values in the lookup index.
This means they can be plotted with correct axis markers, and allows automatic
conversions to between formats with different standards (such as NetCDF and GeoTiff).
"""
abstract type Position <: LookupTrait end
"""
Center <: Position
Center()
Used to specify lookup values correspond to the center locus in an interval.
"""
struct Center <: Position end
"""
Start <: Position
Start()
Used to specify lookup values correspond to the start locus of an interval.
"""
struct Start <: Position end
"""
Begin <: Position
Begin()
Used to specify the `begin` index of a `Dimension` axis,
as regular `begin` will not work with named dimensions.
Can be used with `:` to create a `BeginEndRange` or
`BeginEndStepRange`.
"""
struct Begin <: Position end
"""
End <: Position
End()
Used to specify the `end` index of a `Dimension` axis,
as regular `end` will not work with named dimensions.
Can be used with `:` to create a `BeginEndRange` or
`BeginEndStepRange`.
Also used to specify lookup values correspond to the end
locus of an interval.
"""
struct End <: Position end
"""
AutoPosition <: Position
AutoPosition()
Indicates a interval where the index locus is not yet known.
This will be filled with a default value on object construction.
"""
struct AutoPosition <: Position end
# Locus does not include `Begin`
const Locus = Union{AutoPosition,Start,Center,End}
const AutoLocus = AutoPosition
"""
Sampling <: LookupTrait
Indicates the sampling method used by the index: [`Points`](@ref)
or [`Intervals`](@ref).
"""
abstract type Sampling <: LookupTrait end
struct NoSampling <: Sampling end
locus(sampling::NoSampling) = Center()
struct AutoSampling <: Sampling end
locus(sampling::AutoSampling) = AutoPosition()
"""
Points <: Sampling
Points()
[`Sampling`](@ref) lookup where single samples at exact points.
These are always plotted at the center of array cells.
"""
struct Points <: Sampling end
locus(sampling::Points) = Center()
"""
Intervals <: Sampling
Intervals(locus::Position)
[`Sampling`](@ref) specifying that sampled values are the mean (or similar)
value over an _interval_, rather than at one specific point.
Intervals require a [`locus`](@ref) of [`Start`](@ref), [`Center`](@ref) or
[`End`](@ref) to define the location in the interval that the index values refer to.
"""
struct Intervals{P} <: Sampling
locus::P
end
Intervals() = Intervals(AutoPosition())
locus(sampling::Intervals) = sampling.locus
rebuild(::Intervals, locus) = Intervals(locus)
"""
Span <: LookupTrait
Defines the type of span used in a [`Sampling`](@ref) index.
These are [`Regular`](@ref) or [`Irregular`](@ref).
"""
abstract type Span <: LookupTrait end
struct NoSpan <: Span end
Adapt.adapt_structure(to, s::Span) = s
"""
AutoSpan <: Span
AutoSpan()
The span will be guessed and replaced in `format` or `set`.
"""
struct AutoSpan <: Span end
struct AutoStep end
struct AutoBounds end
struct AutoDim end
"""
Regular <: Span
Regular(step=AutoStep())
`Points` or `Intervals` that have a fixed, regular step.
"""
struct Regular{S} <: Span
step::S
end
Regular() = Regular(AutoStep())
val(span::Regular) = span.step
Base.step(span::Regular) = span.step
Base.:(==)(l1::Regular, l2::Regular) = val(l1) == val(l2)
"""
Irregular <: Span
Irregular(bounds::Tuple)
Irregular(lowerbound, upperbound)
`Points` or `Intervals` that have an `Irregular` step size. To enable bounds tracking
and accurate selectors, the starting bounds are provided as a 2 tuple, or 2 arguments.
`(nothing, nothing)` is acceptable input, the bounds will be guessed from the index,
but may be inaccurate.
"""
struct Irregular{B<:Union{<:Tuple{<:Any,<:Any},AutoBounds}} <: Span
bounds::B
end
Irregular() = Irregular(AutoBounds())
Irregular(lowerbound, upperbound) = Irregular((lowerbound, upperbound))
bounds(span::Irregular) = span.bounds
val(span::Irregular) = span.bounds
Base.:(==)(l1::Irregular, l2::Irregular) = val(l1) == val(l2)
"""
Explicit(bounds::AbstractMatrix)
Intervals where the span is explicitly listed for every interval.
This uses a matrix where with length 2 columns for each index value,
holding the lower and upper bounds for that specific index.
"""
struct Explicit{B} <: Span
val::B
end
Explicit() = Explicit(AutoBounds())
val(span::Explicit) = span.val
Base.:(==)(l1::Explicit, l2::Explicit) = val(l1) == val(l2)
Adapt.adapt_structure(to, s::Explicit) = Explicit(Adapt.adapt_structure(to, val(s)))
"""
AutoValues
Detect `Lookup` values from the context. This is used in `NoLookup` to simply
use the array axis as the index when the array is constructed, and in `set` to
change the `Lookup` type without changing the index values.
"""
struct AutoValues <: AbstractVector{Int} end
Base.size(::AutoValues) = (0,)