From 089fec596f7d936935622626cb3d1c2d4f0277b6 Mon Sep 17 00:00:00 2001 From: gabrieldansereau Date: Thu, 9 Apr 2020 14:44:07 -0400 Subject: [PATCH 1/8] :bug: fix getindex call when omitting crop limit --- src/lib/overloads.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib/overloads.jl b/src/lib/overloads.jl index b83309e1..03a0ed29 100644 --- a/src/lib/overloads.jl +++ b/src/lib/overloads.jl @@ -163,10 +163,10 @@ Returns a subset of the argument layer, where the new limits are given by if so these limits will not be affected. """ function Base.getindex(p::T; left::K=nothing, right::K=nothing, top::K=nothing, bottom::K=nothing) where {T <: SimpleSDMLayer, K <: Union{Nothing,AbstractFloat}} - imax = isnothing(right) ? p.right : match_longitude(p, right) - imin = isnothing(left) ? p.left : match_longitude(p, left) - jmax = isnothing(top) ? p.top : match_latitude(p, top) - jmin = isnothing(bottom) ? p.bottom : match_latitude(p, bottom) + imax = match_longitude(p, isnothing(right) ? p.right : right) + imin = match_longitude(p, isnothing(left) ? p.left : left) + jmax = match_latitude(p, isnothing(top) ? p.top : top) + jmin = match_latitude(p, isnothing(bottom) ? p.bottom : bottom) any(isnan.([imin, imax, jmin, jmax])) && throw(ArgumentError("Unable to extract, coordinates outside of range")) return p[jmin:jmax, imin:imax] end From 43fb3c1e37158027f3332a59aba7f6d1fe26e531 Mon Sep 17 00:00:00 2001 From: gabrieldansereau Date: Thu, 9 Apr 2020 15:26:44 -0400 Subject: [PATCH 2/8] :bug: fix types to omit crop limit --- src/lib/overloads.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/overloads.jl b/src/lib/overloads.jl index 03a0ed29..78c6fe98 100644 --- a/src/lib/overloads.jl +++ b/src/lib/overloads.jl @@ -162,7 +162,7 @@ Returns a subset of the argument layer, where the new limits are given by `left`, `right`, `top`, and `bottom`. Up to three of these can be omitted, and if so these limits will not be affected. """ -function Base.getindex(p::T; left::K=nothing, right::K=nothing, top::K=nothing, bottom::K=nothing) where {T <: SimpleSDMLayer, K <: Union{Nothing,AbstractFloat}} +function Base.getindex(p::T; left::Union{N,A}=nothing, right::Union{N,A}=nothing, top::Union{N,A}=nothing, bottom::Union{N,A}=nothing) where {T <: SimpleSDMLayer, N <: Nothing, A <: AbstractFloat} imax = match_longitude(p, isnothing(right) ? p.right : right) imin = match_longitude(p, isnothing(left) ? p.left : left) jmax = match_latitude(p, isnothing(top) ? p.top : top) From 7af8afeec529b6c6672ba55a808a3bfacce70d2d Mon Sep 17 00:00:00 2001 From: gabrieldansereau Date: Thu, 9 Apr 2020 16:20:55 -0400 Subject: [PATCH 3/8] :sparkles: option to crop on NamedTuple --- src/lib/overloads.jl | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/lib/overloads.jl b/src/lib/overloads.jl index 78c6fe98..647ebf9c 100644 --- a/src/lib/overloads.jl +++ b/src/lib/overloads.jl @@ -171,6 +171,22 @@ function Base.getindex(p::T; left::Union{N,A}=nothing, right::Union{N,A}=nothing return p[jmin:jmax, imin:imax] end +""" + Base.getindex(p::T, n::NT) where {T <: SimpleSDMLayer, NT <: NamedTuple} + +Returns a subset of the argument layer, where the new limits are given in +a NamedTuple by `left`, `right`, `top`, and `bottom`, in any order. Up to +three of these can be omitted, and if so these limits will not be affected. +""" + +function Base.getindex(p::T, n::NT) where {T <: SimpleSDMLayer, NT <: NamedTuple} + l = isdefined(n, :left) ? n.left : nothing + r = isdefined(n, :right) ? n.right : nothing + t = isdefined(n, :top) ? n.top : nothing + b = isdefined(n, :bottom) ? n.bottom : nothing + Base.getindex(p; left = l, right = r, top = t, bottom = b) +end + """ Base.getindex(p1::T1, p2::T2) where {T1 <: SimpleSDMLayer, T2 <: SimpleSDMLayer} From f09773442e3077c4a62e1de98b7bd47543a260f7 Mon Sep 17 00:00:00 2001 From: gabrieldansereau Date: Thu, 9 Apr 2020 16:22:22 -0400 Subject: [PATCH 4/8] :white_check_mark: test for cropping while omitting limit --- test/overloads.jl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/overloads.jl b/test/overloads.jl index 2fc497c2..9bfbd650 100644 --- a/test/overloads.jl +++ b/test/overloads.jl @@ -26,6 +26,15 @@ end @test S[left=0.2, right=0.6, bottom=0.5, top=1.0].right ≈ 0.6 @test S[left=0.2, right=0.6, bottom=0.5, top=1.0].left ≈ 0.2 +@test typeof(S[left=0.2, bottom=0.5]) == typeof(S) +@test S[left=0.2, bottom=0.5].top ≈ 1.0 +@test S[left=0.2, bottom=0.5].bottom ≈ 0.4 +@test S[left=0.2, bottom=0.5].right ≈ 1.0 +@test S[left=0.2, bottom=0.5].left ≈ 0.2 + +C = (left=0.2, bottom=0.5) +@test typeof(S[C]) == typeof(S) + Y = SimpleSDMResponse(zeros(Float64, (5,5)), 0.0, 1.0, 0.0, 1.0) Y[0.1,0.1] = 0.2 @test Y[0.1,0.1] == 0.2 From 5bc369e334ff030f885703d497f794a218721898 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e?= Date: Thu, 9 Apr 2020 21:03:52 -0400 Subject: [PATCH 5/8] Remove the types from the getindex with keywords --- src/lib/overloads.jl | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/lib/overloads.jl b/src/lib/overloads.jl index 647ebf9c..4138eab0 100644 --- a/src/lib/overloads.jl +++ b/src/lib/overloads.jl @@ -156,13 +156,18 @@ function Base.getindex(p::T, longitude::K, latitude::K) where {T <: SimpleSDMLay end """ - Base.getindex(p::T; left::K=nothing, right::K=nothing, top::K=nothing, bottom::K=nothing) where {T <: SimpleSDMLayer, K <: Union{Nothing,AbstractFloat}} + Base.getindex(p::T; left=nothing, right=nothing, top=nothing, bottom=nothing) where {T <: SimpleSDMLayer, K <: Union{Nothing,AbstractFloat}} Returns a subset of the argument layer, where the new limits are given by `left`, `right`, `top`, and `bottom`. Up to three of these can be omitted, and if so these limits will not be affected. """ -function Base.getindex(p::T; left::Union{N,A}=nothing, right::Union{N,A}=nothing, top::Union{N,A}=nothing, bottom::Union{N,A}=nothing) where {T <: SimpleSDMLayer, N <: Nothing, A <: AbstractFloat} +function Base.getindex(p::T; left=nothing, right=nothing, top=nothing, bottom=nothing) where {T <: SimpleSDMLayer} + for limit in [left, right, top, bottom] + if !isnothing(limit) + @assert typeof(limit) <: AbstractFloat + end + end imax = match_longitude(p, isnothing(right) ? p.right : right) imin = match_longitude(p, isnothing(left) ? p.left : left) jmax = match_latitude(p, isnothing(top) ? p.top : top) From e19674d611148da2f9bc51606c0c57a51d74bc5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e?= Date: Thu, 9 Apr 2020 21:04:10 -0400 Subject: [PATCH 6/8] Add a minor version bump --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 20128cdc..a1a35b08 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "SimpleSDMLayers" uuid = "2c645270-77db-11e9-22c3-0f302a89c64c" authors = ["Timothée Poisot "] -version = "0.2.0" +version = "0.2.1" [deps] GDAL = "add2ef01-049f-52c4-9ee2-e494f65e021a" From df932eb5073506b0bf668d504fae760f8b4cc4ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e?= Date: Thu, 9 Apr 2020 21:05:10 -0400 Subject: [PATCH 7/8] fix whitespace between function and documentation block --- src/lib/overloads.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib/overloads.jl b/src/lib/overloads.jl index 4138eab0..d7071231 100644 --- a/src/lib/overloads.jl +++ b/src/lib/overloads.jl @@ -183,7 +183,6 @@ Returns a subset of the argument layer, where the new limits are given in a NamedTuple by `left`, `right`, `top`, and `bottom`, in any order. Up to three of these can be omitted, and if so these limits will not be affected. """ - function Base.getindex(p::T, n::NT) where {T <: SimpleSDMLayer, NT <: NamedTuple} l = isdefined(n, :left) ? n.left : nothing r = isdefined(n, :right) ? n.right : nothing From b5537f2bf8840d49b1c5237d9f8b0a746236a133 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e?= Date: Thu, 9 Apr 2020 21:06:56 -0400 Subject: [PATCH 8/8] preface non-exported functions with _ --- src/lib/overloads.jl | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/lib/overloads.jl b/src/lib/overloads.jl index d7071231..6fdaeca0 100644 --- a/src/lib/overloads.jl +++ b/src/lib/overloads.jl @@ -125,7 +125,7 @@ end Given a layer and a latitude, returns NaN if the latitude is outside the range, or the grid index containing this latitude if it is within range """ -function match_latitude(p::T, l::K) where {T <: SimpleSDMLayer, K <: AbstractFloat} +function _match_latitude(p::T, l::K) where {T <: SimpleSDMLayer, K <: AbstractFloat} l > p.top && return NaN l < p.bottom && return NaN return findmin(abs.(l .- latitudes(p)))[2] @@ -135,7 +135,7 @@ end Given a layer and a longitude, returns NaN if the longitude is outside the range, or the grid index containing this longitude if it is within range """ -function match_longitude(p::T, l::K) where {T <: SimpleSDMLayer, K <: AbstractFloat} +function _match_longitude(p::T, l::K) where {T <: SimpleSDMLayer, K <: AbstractFloat} l > p.right && return NaN l < p.left && return NaN return findmin(abs.(l .- longitudes(p)))[2] @@ -148,8 +148,8 @@ Extracts the value of a layer at a given latitude and longitude. If values outside the range are requested, will return `NaN`. """ function Base.getindex(p::T, longitude::K, latitude::K) where {T <: SimpleSDMLayer, K <: AbstractFloat} - i = match_longitude(p, longitude) - j = match_latitude(p, latitude) + i = _match_longitude(p, longitude) + j = _match_latitude(p, latitude) isnan(i) && return NaN isnan(j) && return NaN return p.grid[j, i] @@ -168,10 +168,10 @@ function Base.getindex(p::T; left=nothing, right=nothing, top=nothing, bottom=no @assert typeof(limit) <: AbstractFloat end end - imax = match_longitude(p, isnothing(right) ? p.right : right) - imin = match_longitude(p, isnothing(left) ? p.left : left) - jmax = match_latitude(p, isnothing(top) ? p.top : top) - jmin = match_latitude(p, isnothing(bottom) ? p.bottom : bottom) + imax = _match_longitude(p, isnothing(right) ? p.right : right) + imin = _match_longitude(p, isnothing(left) ? p.left : left) + jmax = _match_latitude(p, isnothing(top) ? p.top : top) + jmin = _match_latitude(p, isnothing(bottom) ? p.bottom : bottom) any(isnan.([imin, imax, jmin, jmax])) && throw(ArgumentError("Unable to extract, coordinates outside of range")) return p[jmin:jmax, imin:imax] end @@ -221,8 +221,8 @@ Changes the values of the cell including the point at the requested latitude and longitude. """ function Base.setindex!(p::SimpleSDMResponse{T}, v::T, lon::Float64, lat::Float64) where {T} - i = match_longitude(p, lon) - j = match_latitude(p, lat) + i = _match_longitude(p, lon) + j = _match_latitude(p, lat) p[j,i] = v end