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

Always wrap variables in ModifiedDiskArray even when it does nothing #892

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
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
4 changes: 2 additions & 2 deletions ext/RastersArchGDALExt/gdal_source.jl
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ function Base.write(filename::AbstractString, ::GDALsource, A::AbstractRaster{T}
if write
mod = RA._mod(eltype, missingval_pair, scale, offset, coerce)
open(A1; write=true) do O
R = RA._maybe_modify(AG.RasterDataset(dataset), mod)
R = RA.ModifiedDiskArray(AG.RasterDataset(dataset), mod)
R .= parent(O)
if hasdim(A, Band())
f(R)
Expand Down Expand Up @@ -296,7 +296,7 @@ function AG.RasterDataset(f::Function, A::AbstractRaster;
rds = AG.RasterDataset(dataset)
mv = RA.missingval(rds) => RA.missingval(O)
mod = RA._mod(eltype, mv, scale, offset, coerce)
RA._maybe_modify(rds, mod) .= parent(O)
RA.ModifiedDiskArray(rds, mod) .= parent(O)
f(rds)
end
end
Expand Down
2 changes: 1 addition & 1 deletion src/Rasters.jl
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ using ColorTypes: RGB

using CommonDataModel: AbstractDataset, AbstractVariable

using DiskArrays: @implement_diskarray
import DiskArrays: @implement_diskarray, isdisk

using GeometryOpsCore: Planar, Spherical
export Planar, Spherical
Expand Down
8 changes: 4 additions & 4 deletions src/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ filename(A::DiskArrays.AbstractDiskArray) = filename(parent(A))
cleanreturn(A::AbstractRaster) = rebuild(A, cleanreturn(parent(A)))
cleanreturn(x) = x

isdisk(A::AbstractRaster) = parent(A) isa DiskArrays.AbstractDiskArray
isdisk(x) = false
DiskArrays.isdisk(A::AbstractRaster) = isdisk(parent(A))
DiskArrays.isdisk(x) = false
ismem(A::AbstractRaster) = !isdisk(A)

function Base.:(==)(A::AbstractRaster{T,N}, B::AbstractRaster{T,N}) where {T,N}
Expand Down Expand Up @@ -298,7 +298,7 @@ function Raster(filename::AbstractString;
kw...
)
source = sourcetrait(filename, source)
_open(filename; source, mod=NoMod()) do ds
_open(filename; source, mod=nothing) do ds
Raster(ds, filename; source, kw...)
end::Raster
end
Expand Down Expand Up @@ -334,7 +334,7 @@ function Raster(ds, filename::AbstractString;
source = sourcetrait(filename, source)
# Open the dataset and variable specified by `name`, at `group` level if provided
# At this level we do not apply `mod`.
data_out, dims_out, metadata_out, missingval_out = _open(source, ds; name=name1, group, mod=NoMod()) do var
data_out, dims_out, metadata_out, missingval_out = _open(source, ds; name=name1, group, mod=nothing) do var
metadata_out = isnokw(metadata) ? _metadata(var) : metadata
missingval_out = _read_missingval_pair(var, metadata_out, missingval)
# Generate mod for scaling
Expand Down
12 changes: 10 additions & 2 deletions src/filearray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,20 @@ end

function DA.readblock!(A::FileArray, dst, r::AbstractUnitRange...)
open(A) do O
DA.readblock!(O, dst, r...)
if isdisk(O)
DA.readblock!(O, dst, r...)
else
dest[r...] .= view(parent(O), r...)
end
end
end
function DA.writeblock!(A::FileArray, src, r::AbstractUnitRange...)
open(A; write=A.write) do O
DA.writeblock!(O, src, r...)
if isdisk(A)
DA.writeblock!(O, src, r...)
else
parent(O)[r...] .= src
end
end
end

Expand Down
106 changes: 54 additions & 52 deletions src/modifieddiskarray.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
abstract type AbstractModifications end
struct NoMod{T,Mi} <: AbstractModifications

abstract type AbstractModifications{T} end

struct NoMod{T,Mi} <: AbstractModifications{T}
missingval::Mi
end
NoMod{T}(missingval::Mi) where {T,Mi} = NoMod{T,Mi}(missingval)
Expand All @@ -10,7 +12,8 @@ NoMod{T}(::NoKW) where T = NoMod{T}(nothing)
Base.eltype(::NoMod{T}) where T = T
source_eltype(::NoMod{T}) where T = T

struct Mod{T1,T2,Mi,S,O,F} <: AbstractModifications
# Modifies array values by scale
struct Mod{T1,T2,Mi,S,O,F} <: AbstractModifications{T1}
missingval::Mi
scale::S
offset::O
Expand Down Expand Up @@ -48,71 +51,73 @@ _outer_missingval(m::AbstractModifications) = _outer_missingval(m.missingval)
_outer_missingval(mv::Pair) = mv[2]
_outer_missingval(mv) = mv

struct ModifiedDiskArray{I,T,N,V,M} <: DiskArrays.AbstractDiskArray{T,N}
var::V
# A wrapper for disk arrays that modifieds values lazily:
# scale and offset or replacing missing values
struct ModifiedDiskArray{T,N,D,M} <: DiskArrays.AbstractDiskArray{T,N}
data::D
mod::M
end
function ModifiedDiskArray(v::V, m::M; invert=false) where {V<:AbstractArray{<:Any,N},M} where N
T = invert ? source_eltype(m) : eltype(m)
return ModifiedDiskArray{invert,T,N,V,M}(v, m)
function ModifiedDiskArray(
data::D, mod::M
) where {D<:AbstractArray{<:Any,N},M<:AbstractModifications{T}} where {T,N}
return ModifiedDiskArray{T,N,D,M}(data, mod)
end

Base.parent(A::ModifiedDiskArray) = A.var
Base.size(A::ModifiedDiskArray, args...) = size(parent(A), args...)
_maybe_modify(A::AbstractArray, mod::AbstractModifications) =
ModifiedDiskArray(A, mod)
_maybe_modify(A::AbstractArray, ::Nothing) = A

filename(A::ModifiedDiskArray) = filename(parent(A))
missingval(A::ModifiedDiskArray) = A.missingval
_metadata(A::ModifiedDiskArray, args...) = _metadata(parent(A), args...)

Base.parent(A::ModifiedDiskArray) = A.data
Base.size(A::ModifiedDiskArray, args...) = size(parent(A), args...)

DiskArrays.haschunks(A::ModifiedDiskArray) = DiskArrays.haschunks(parent(A))
DiskArrays.eachchunk(A::ModifiedDiskArray) = DiskArrays.eachchunk(parent(A))

function DiskArrays.readblock!(
A::ModifiedDiskArray{false,<:Any,0}, out_block, I::AbstractVector...
A::ModifiedDiskArray{<:Any,<:Any,<:Any,<:Mod}, outer_block, I::AbstractVector...
)
out_block[] = _applymod(parent(A)[I...][], A.mod)
return out_block
end
function DiskArrays.readblock!(
A::ModifiedDiskArray{true,T,<:Any,0}, out_block, I::AbstractVector...
) where T
out_block[] = _invertmod(Val{T}(), parent(A)[I...], A.mod)
return out_block
if isdisk(parent(A))
inner_block = similar(outer_block, eltype(parent(A)))
DiskArrays.readblock!(parent(A), inner_block, I...)
outer_block .= _applymod.(inner_block, (A.mod,))
else
inner_block = view(parent(A), I...)
outer_block .= _applymod.(inner_block, (A.mod,))
end
return outer_block
end
function DiskArrays.readblock!(
A::ModifiedDiskArray{false}, out_block, I::AbstractVector...
A::ModifiedDiskArray{<:Any,<:Any,<:Any,<:NoMod}, out_block, I::AbstractVector...
)
out_block .= _applymod.(parent(A)[I...], (A.mod,))
return out_block
end
function DiskArrays.readblock!(
A::ModifiedDiskArray{true,T}, out_block, I::AbstractVector...
) where T
out_block .= _invertmod.((Val{T}(),), parent(A)[I...], (A.mod,))
return out_block
if isdisk(parent(A))
DiskArrays.readblock!(parent(A), out_block, I...)
else
out_block .= view(parent(A), I...)
end
end

function DiskArrays.writeblock!(
A::ModifiedDiskArray{false,<:Any,0,<:AbstractArray{T}}, block, I::AbstractVector...
) where T

parent(A)[I...] = _invertmod(Val{source_eltype(A.mod)}(), block[], A.mod)
return nothing
end
function DiskArrays.writeblock!(
A::ModifiedDiskArray{true,<:Any,0,<:AbstractArray{T}}, _block, I::AbstractVector...
) where T
parent(A)[I...] = _applymod(Val{eltype(A.mod)}(), block[], A.mod)
return nothing
end
function DiskArrays.writeblock!(
A::ModifiedDiskArray{<:Any,<:Any,<:Any,<:AbstractArray{T}}, block, I::AbstractVector...
) where T
parent(A)[I...] = _invertmod.((Val{source_eltype(A.mod)}(),), block, (A.mod,))
return nothing
A::ModifiedDiskArray{<:Any,<:Any,<:Any,<:Mod}, block, I::AbstractVector...
)
if isdisk(parent(A))
modblock = _invertmod.((Val{source_eltype(A.mod)}(),), block, (A.mod,))
return DiskArrays.writeblock!(parent(A), modblock, I...)
else
parent(A)[I...] = _invertmod.((Val{source_eltype(A.mod)}(),), block, (A.mod,))
end
end
function DiskArrays.writeblock!(
A::ModifiedDiskArray{true,<:Any,<:Any,<:AbstractArray{T}}, _block, I::AbstractVector...
) where T
parent(A)[I...] = _applymod.((Val{eltype(A.mod)}(),), block, (A.mod,))
return nothing
A::ModifiedDiskArray{<:Any,<:Any,<:Any,<:NoMod}, block, I::AbstractVector...
)
if isdisk(parent(A))
DiskArrays.writeblock!(parent(A), block, I...)
else
parent(A)[I...] = block
end
end

Base.@assume_effects :foldable function _applymod(x, m::Mod)
Expand Down Expand Up @@ -197,9 +202,6 @@ _mod_inverse_eltype(::AbstractArray{T}, ::NoMod) where T = T
_mod_inverse_eltype(::AbstractArray{T}, m::Mod) where T =
Base.promote_op(_invertmod, typeof(m.coerce), T, typeof(m))

_maybe_modify(var, m::Mod; kw...) = ModifiedDiskArray(var, m; kw...)
_maybe_modify(var, ::NoMod; kw...) = var

_write_missingval_pair(A, missingval::Pair; kw...) = missingval
function _write_missingval_pair(A, missingval;
verbose=true, eltype, metadata=metadata(A), required=false
Expand Down
2 changes: 1 addition & 1 deletion src/openstack.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ struct OpenStack{X,K,T,DS,M}
mods::M
end
function OpenStack{X,K,T}(
dataset::DS, mods::M=NoMod()
dataset::DS, mods::M
) where {X,K,T,DS,M}
OpenStack{X,K,T,DS,M}(dataset, mods)
end
Expand Down
3 changes: 2 additions & 1 deletion src/series.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ abstract type AbstractRasterSeries{T,N,D,A} <: AbstractDimArray{T,N,D,A} end
DD.metadata(A::AbstractRasterSeries) = NoMetadata()
DD.name(A::AbstractRasterSeries) = NoName()
DD.label(A::AbstractRasterSeries) = ""
isdisk(A::AbstractRasterSeries) = any(isdisk, A)

DiskArrays.isdisk(A::AbstractRasterSeries) = any(isdisk, A)

"""
modify(f, series::AbstractRasterSeries)
Expand Down
6 changes: 3 additions & 3 deletions src/sources/commondatamodel.jl
Original file line number Diff line number Diff line change
Expand Up @@ -499,10 +499,10 @@ function Base.write(filename::AbstractString, source::Source, s::AbstractRasterS
ds = sourceconstructor(source)(filename, mode; attrib=_attribdict(metadata(s)))
missingval = _stack_nt(s, isnokw(missingval) ? Rasters.missingval(s) : missingval)
try
map(keys(s)) do k
mods = map(keys(s)) do k
writevar!(ds, source, s[k]; missingval=missingval[k], kw...)
end
f(OpenStack{Source,K,T}(ds))
f(OpenStack{Source,K,T}(ds, mods))
finally
close(ds)
end
Expand Down Expand Up @@ -578,7 +578,7 @@ function writevar!(ds::AbstractDataset, source::CDMsource, A::AbstractRaster{T,N
f(m)
end

return nothing
return mod
end

const CDMallowedType = Union{Int8,UInt8,Int16,UInt16,Int32,UInt32,Int64,UInt64,Float32,Float64,Char,String}
Expand Down
7 changes: 3 additions & 4 deletions src/stack.jl
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ filename(stack::AbstractRasterStack{<:Any,<:Any,<:Any,<:NamedTuple}) =
filename(stack::AbstractRasterStack{<:Any,<:Any,<:Any,<:Union{FileStack,OpenStack}}) =
filename(parent(stack))

isdisk(st::AbstractRasterStack) = any(isdisk, layers(st))
DiskArrays.isdisk(st::AbstractRasterStack) = any(isdisk, layers(st))

setcrs(x::AbstractRasterStack, crs) = set(x, setcrs(dims(x), crs)...)
setmappedcrs(x::AbstractRasterStack, mappedcrs) = set(x, setmappedcrs(dims(x), mappedcrs)...)
Expand Down Expand Up @@ -557,10 +557,9 @@ function _layer_stack(filename;
FileStack{typeof(source)}(ds, filename; name, group, mods, vars)
else
map(layers.vars, layermetadata_vec, mod_vec) do var, md, mod
modvar = _maybe_modify(var, mod)
modvar = ModifiedDiskArray(var, mod)
checkmem && _checkobjmem(modvar)
x = Array(modvar)
x isa AbstractArray ? x : fill(x) # Catch an NCDatasets bug
Array(modvar)
end |> NT
end
mv_outer = NT(map(_outer_missingval, mod_vec))
Expand Down
2 changes: 1 addition & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ end
@time @safetestset "sources" begin include("sources/sources.jl") end
@time @safetestset "commondatamodel" begin include("sources/commondatamodel.jl") end
@time @safetestset "ncdatasets" begin include("sources/ncdatasets.jl") end
@time @safetestset "zarrdatasets" begin include("sources/zarr.jl") end
# @time @safetestset "zarrdatasets" begin include("sources/zarr.jl") end
if !Sys.iswindows()
# GRIBDatasets doesn't work on Windows for now
@time @safetestset "gribdatasets" begin include("sources/gribdatasets.jl") end
Expand Down
2 changes: 1 addition & 1 deletion test/series.jl
Original file line number Diff line number Diff line change
Expand Up @@ -127,5 +127,5 @@ end
@test Rasters.isdisk(series)
@test !Rasters.isdisk(read(series))
@test Rasters.isdisk(Rasters.combine(series))
end
end
end
6 changes: 0 additions & 6 deletions test/sources/grd.jl
Original file line number Diff line number Diff line change
Expand Up @@ -325,12 +325,6 @@ end
@test parent(eagerstack[:a]) isa Array
end

@testset "replace_missing keyword" begin
st = RasterStack((a=grdpath, b=grdpath); replace_missing=true)
@test eltype(st) == @NamedTuple{a::Union{Missing,Float32},b::Union{Missing,Float32}}
@test missingval(st) === missing
end

@test length(layers(grdstack)) == 2
@test dims(grdstack) isa Tuple{<:X,<:Y,<:Band}

Expand Down
4 changes: 2 additions & 2 deletions test/sources/ncdatasets.jl
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,10 @@ end
@test parent(nocf_nomask_array) isa Array{Float32}
@test parent(raw_array) isa Array{Float32}
open(lazycfarray) do A
@test parent(A) isa Rasters.ModifiedDiskArray{false,Union{Missing,Float32}}
@test parent(A) isa Rasters.ModifiedDiskArray{Union{Missing,Float32}}
end
open(lazynocfarray) do A
@test parent(A) isa Rasters.ModifiedDiskArray{false,Union{Missing,Float32}}
@test parent(A) isa Rasters.ModifiedDiskArray{Union{Missing,Float32}}
end
open(lazynocf_nomask_array) do A
@test parent(parent(A)) isa NCDatasets.Variable{Float32}
Expand Down
Loading