Commit 8ff49a46 authored by Dan Baston's avatar Dan Baston

Correctly append to files having unlimited dimensions

parent b9ffb0cb
#' Create netCDF dimensions
#'
#' @inheritParams write_vars_to_cdf
#' @param unlimited_dims character vector of dimension names which should
#' be created as unlimited
#' @return list of \code{ncdim4} objects
#'
make_netcdf_dims <- function(vars, extent, ids, extra_dims) {
c(make_netcdf_base_dims(vars, extent, ids),
make_netcdf_extra_dims(extra_dims))
make_netcdf_dims <- function(vars, extent, ids, extra_dims, unlimited_dims=NULL) {
c(make_netcdf_base_dims(vars, extent, ids, unlimited_dims),
make_netcdf_extra_dims(extra_dims, unlimited_dims))
}
make_netcdf_base_dims <- function(vars, extent, ids) {
make_netcdf_base_dims <- function(vars, extent, ids, unlimited_dims=NULL) {
is_spatial <- is.null(ids)
if (is_spatial) {
......@@ -16,8 +18,18 @@ make_netcdf_base_dims <- function(vars, extent, ids) {
lons <- lon_seq(extent, dim(vars[[1]]))
return(list(
lon = ncdf4::ncdim_def("lon", units="degrees_east", vals=lons, longname="Longitude", create_dimvar=TRUE),
lat = ncdf4::ncdim_def("lat", units="degrees_north", vals=lats, longname="Latitude", create_dimvar=TRUE)
lon = ncdf4::ncdim_def("lon",
units="degrees_east",
vals=lons,
longname="Longitude",
create_dimvar=TRUE,
unlim="lon" %in% unlimited_dims),
lat = ncdf4::ncdim_def("lat",
units="degrees_north",
vals=lats,
longname="Latitude",
create_dimvar=TRUE,
unlim="lat" %in% unlimited_dims)
))
} else {
if (mode(ids) == 'character') {
......@@ -25,26 +37,36 @@ make_netcdf_base_dims <- function(vars, extent, ids) {
# old-school way, with fixed-length character arrays. Data written in this
# way seems to be interpreted correctly by software such as QGIS.
return(list(
id = ncdf4::ncdim_def("id", units="", vals=1:length(ids), create_dimvar=FALSE)
id = ncdf4::ncdim_def("id",
units="",
vals=1:length(ids),
create_dimvar=FALSE,
unlim="id" %in% unlimited_dims)
))
} else {
# integer ids
return(list(
id = ncdf4::ncdim_def("id", units="", vals=ids, create_dimvar=TRUE)
id = ncdf4::ncdim_def("id",
units="",
vals=ids,
create_dimvar=TRUE,
unlim="id" %in% unlimited_dims)
))
}
}
}
make_netcdf_extra_dims <- function(extra_dims) {
make_netcdf_extra_dims <- function(extra_dims, unlimited_dims=NULL) {
extra_ncdf_dims <- list()
for (dimname in names(extra_dims)) {
vals <- extra_dims[[dimname]]
unlim <- dimname %in% unlimited_dims
if (mode(vals) == 'character') {
new_dim <- ncdf4::ncdim_def(dimname, units='', vals=1:length(vals), create_dimvar=FALSE)
new_dim <- ncdf4::ncdim_def(dimname, units='', vals=1:length(vals), create_dimvar=FALSE, unlim=unlim)
} else {
new_dim <- ncdf4::ncdim_def(dimname, units='', vals=vals, create_dimvar=TRUE)
new_dim <- ncdf4::ncdim_def(dimname, units='', vals=vals, create_dimvar=TRUE, unlim=unlim)
}
extra_ncdf_dims[[dimname]] <- new_dim
}
......
......@@ -130,9 +130,12 @@ write_vars_to_cdf <- function(vars,
if (append && file.exists(filename)) {
ncout <- ncdf4::nc_open(filename, write=TRUE)
unlimited_dims <- Filter(function(dimname) ncout$dim[[dimname]]$unlim,
names(ncout$dim))
# Verify that our dimensions match up before writing
if (!quick_append) {
dims <- make_netcdf_dims(vars, extent, ids, extra_dims)
dims <- make_netcdf_dims(vars, extent, ids, extra_dims, unlimited_dims)
ncvars <- create_vars(vars, dims, ids, prec, extra_dims)
# Check that the dimensions of the data to write match up
......
# Copyright (c) 2018 ISciences, LLC.
# Copyright (c) 2018-2019 ISciences, LLC.
# All rights reserved.
#
# WSIM is licensed under the Apache License, Version 2.0 (the "License").
......@@ -527,7 +527,7 @@ test_that('we can append to a file created with an unlimited id dim', {
runoff <- precip*runif(length(ids))
id_dim <- ncdf4::ncdim_def('id', units='', vals=ids, unlim=TRUE)
precip_var <- ncdf4::ncvar_def('precip', units='mm', dim=id_dim)
precip_var <- ncdf4::ncvar_def('precip', units='mm', dim=id_dim, compression=1)
cdf <- ncdf4::nc_create(fname, precip_var)
ncdf4::ncvar_put(cdf, precip_var, precip)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment