Skip to content

Commit

Permalink
issue #211
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexander-Barth committed Jun 21, 2023
1 parent 334f221 commit 22b44ff
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 3 deletions.
28 changes: 25 additions & 3 deletions src/variable.jl
Original file line number Diff line number Diff line change
Expand Up @@ -86,18 +86,28 @@ variable(ds::NCDataset,varname::Symbol) = _variable(ds,varname)
export variable


function checkbuffer(len,data)
if length(data) != len
throw(DimensionMismatch("expected an array with $(len) elements, but got an arrow with $(length(data)) elements"))
end
end

"""
NCDatasets.load!(ncvar::Variable, data, indices)
Loads a NetCDF variables `ncvar` in-place and puts the result in `data` along the
specified `indices`.
specified `indices`. One can use @inbounds annotate code where
bounds checking can be elided by the compiler (which typically require
type-stable code).
```julia
ds = Dataset("file.nc")
ncv = ds["vgos"].var;
# data must have the right shape and type
data = zeros(eltype(ncv),size(ncv));
NCDatasets.load!(ncv,data,:,:,:)
# or
# @inbounds NCDatasets.load!(ncv,data,:,:,:)
close(ds)
# loading a subset
Expand All @@ -106,19 +116,31 @@ load!(ds["temp"].var,data,:,1) # loads the 1st column
```
"""
@inline function load!(ncvar::Variable{T,N}, data, indices::Union{Integer, UnitRange, StepRange, Colon}...) where {T,N}
@inline function load!(ncvar::Variable{T,N}, data::AbstractArray{T}, indices::Union{Integer, UnitRange, StepRange, Colon}...) where {T,N}
sizes = size(ncvar)
normalizedindices = normalizeindexes(sizes, indices)
ind = to_indices(ncvar,normalizedindices)

start,count,stride,jlshape = ncsub(ind)

@boundscheck begin
checkbounds(ncvar,indices...)
checkbuffer(prod(count),data)
end

nc_get_vars!(ncvar.ds.ncid,ncvar.varid,start,count,stride,data)
end

@inline function load!(ncvar::Variable{T,2}, data, i::Colon,j::UnitRange) where T
@inline function load!(ncvar::Variable{T,2}, data::AbstractArray{T}, i::Colon,j::UnitRange) where T
# reversed and 0-based
start = [first(j)-1,0]
count = [length(j),size(ncvar,1)]

@boundscheck begin
checkbounds(ncvar,i,j)
checkbuffer(prod(count),data)
end

nc_get_vara!(ncvar.ds.ncid,ncvar.varid,start,count,data)
end

Expand Down
13 changes: 13 additions & 0 deletions test/test_variable.jl
Original file line number Diff line number Diff line change
Expand Up @@ -275,3 +275,16 @@ data = [1,2,3]
ncv = defVar(ds,"data",data,("data",))
@test isempty(ncv[Int[]])
close(ds)

# issue 211
filename = tempname()
ds = NCDataset(filename, "c")
data = [1,2,3]
ncv = defVar(ds,"data",data,("data",))
data2 = zeros(Int,1)
# data2 too small
@test_throws DimensionMismatch NCDatasets.load!(ds["data"].var,data2,:)

data2 = zeros(Int,10)
# asking too many elements
@test_throws BoundsError NCDatasets.load!(ds["data"].var,data2,1:10)

0 comments on commit 22b44ff

Please sign in to comment.