Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document shiftlocus #922

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/src/api/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ broadcast_dims!
mergedims
unmergedims
reorder
setlocus
maybesetlocus
```

# Global lookup strictness settings
Expand Down
40 changes: 40 additions & 0 deletions docs/src/object_modification.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,3 +190,43 @@ set(A, Y => Unordered)
````

:::


### `shiftlocus`

Sometimes we want to change to position of the lookup values within the
intervals they represent. (what we call the "locus" in DimensionalData.jl).
For example, the coordinates of pixels in GDAL rasters are specified by their
corners. But in NetCDF files, the standard is to use the center of the pixel.
So, to write from one to the other, we need to call [`shiftlocus`](@ref).
This will update the values of the range or vector in the lookup, and change
the `sampling` from e.g. `Intervals{Start}()` to `Intervals{Center}()`.

First define an array with `Start` locii:

```julia shiftlocus
using DimensionalData
using DimensionalData.Lookups # Make more functions and types available
A = ones(X(1.0:3.0; sampling=Intervals(Start())),
Y(10.0:2:20.0; sampling=Intervals(Start())))
```

Then we can shift the locii to the center of each interval
```julia
shiftlocus(Center, A)
```

Or just shift X
```julia
shiftlocus(A)
```

You can also use [`maybeshiftlocus`](@ref) to do the same thing,
but only where it is absolutely needed:

```julia shiftlocus
maybeshiftlocus(Center, A)
```

The difference is if the locus is already what you specify `maybeshiftlocus` will
not give you a new `Array`, instead just returning the input object unchanged.
17 changes: 12 additions & 5 deletions src/Lookups/utils.jl
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@

"""
shiftlocus(locus::Locus, x)

Shift the values of `x` from the current locus to the new locus.
Shift the interval positions in `x` from the current locus
to the new locus, e.g. from [`Center`](@ref) to [`Start`](@ref).

We only shift `Sampled`, `Regular` or `Explicit`, `Intervals`.
We only shift `Sampled` with `Regular` or `Explicit` `Intervals`.
"""
function shiftlocus(locus::Locus, lookup::Lookup)
samp = sampling(lookup)
Expand All @@ -12,6 +14,7 @@ function shiftlocus(locus::Locus, lookup::Lookup)
newlookup = rebuild(lookup; data=newvalues)
return set(newlookup, locus)
end
shiftlocus(locus::Type{T}, lookup) where T<:Locus = shiftlocus(T(), lookup)

# Fallback - no shifting
_shiftlocus(locus::Locus, lookup::Lookup) = parent(lookup)
Expand Down Expand Up @@ -54,7 +57,14 @@ _offset(::End, ::Start) = -1
_offset(::End, ::Center) = -0.5
_offset(::T, ::T) where T<:Locus = 0

"""
maybeshiftlocus(locus::Locus, l::Lookup)

`shiftlocus` that does not error where the specified
shifts are not possible, such as for `Points` sampling.
"""
maybeshiftlocus(locus::Locus, l::Lookup) = _maybeshiftlocus(locus, sampling(l), l)
maybeshiftlocus(locus::Type{T}, l) where T<:Locus = maybeshiftlocus(T(), l)

_maybeshiftlocus(locus::Locus, sampling::Intervals, l::Lookup) = shiftlocus(locus, l)
_maybeshiftlocus(locus::Locus, sampling::Sampling, l::Lookup) = l
Expand Down Expand Up @@ -111,9 +121,6 @@ end
_order(A) = first(A) <= last(A) ? ForwardOrdered() : ReverseOrdered()
_order(A::AbstractArray{<:IntervalSets.Interval}) = first(A).left <= last(A).left ? ForwardOrdered() : ReverseOrdered()

@deprecate maybeshiftlocus maybeshiftlocus
@deprecate shiftlocus shiftlocus

# Remove objects of type T from a
Base.@assume_effects :foldable _remove(::Type{T}, x, xs...) where T = (x, _remove(T, xs...)...)
Base.@assume_effects :foldable _remove(::Type{T}, ::T, xs...) where T = _remove(T, xs...)
Expand Down
Loading