ncmeta/ 0000755 0001762 0000144 00000000000 14520367022 011522 5 ustar ligges users ncmeta/NAMESPACE 0000644 0001762 0000144 00000003426 14520356511 012747 0 ustar ligges users # Generated by roxygen2: do not edit by hand
S3method(nc_att,NetCDF)
S3method(nc_att,character)
S3method(nc_atts,NetCDF)
S3method(nc_atts,character)
S3method(nc_axes,NetCDF)
S3method(nc_axes,character)
S3method(nc_axis,NetCDF)
S3method(nc_axis,character)
S3method(nc_coord_var,NetCDF)
S3method(nc_coord_var,character)
S3method(nc_dim,NetCDF)
S3method(nc_dim,character)
S3method(nc_dim,ncdf4)
S3method(nc_dims,NetCDF)
S3method(nc_dims,character)
S3method(nc_dims,ncdf4)
S3method(nc_gm_to_prj,data.frame)
S3method(nc_gm_to_prj,list)
S3method(nc_grid_mapping_atts,NetCDF)
S3method(nc_grid_mapping_atts,character)
S3method(nc_grid_mapping_atts,data.frame)
S3method(nc_grids,NetCDF)
S3method(nc_grids,character)
S3method(nc_grids,tidync)
S3method(nc_inq,NetCDF)
S3method(nc_inq,character)
S3method(nc_meta,NetCDF)
S3method(nc_meta,character)
S3method(nc_sources,character)
S3method(nc_var,NetCDF)
S3method(nc_var,character)
S3method(nc_vars,NetCDF)
S3method(nc_vars,character)
export(nc_att)
export(nc_atts)
export(nc_axes)
export(nc_axis)
export(nc_coord_var)
export(nc_dim)
export(nc_dims)
export(nc_gm_to_prj)
export(nc_grid_mapping_atts)
export(nc_grids)
export(nc_inq)
export(nc_meta)
export(nc_prj_to_gridmapping)
export(nc_sources)
export(nc_var)
export(nc_vars)
importFrom(RNetCDF,file.inq.nc)
importFrom(dplyr,"%>%")
importFrom(dplyr,arrange)
importFrom(dplyr,bind_rows)
importFrom(dplyr,desc)
importFrom(dplyr,distinct)
importFrom(dplyr,filter)
importFrom(dplyr,group_by)
importFrom(dplyr,left_join)
importFrom(dplyr,mutate)
importFrom(dplyr,row_number)
importFrom(dplyr,select)
importFrom(dplyr,transmute)
importFrom(dplyr,ungroup)
importFrom(rlang,.data)
importFrom(stats,setNames)
importFrom(tibble,as_tibble)
importFrom(tibble,tibble)
ncmeta/README.md 0000644 0001762 0000144 00000006354 14520356511 013012 0 ustar ligges users
[](https://github.com/hypertidy/ncmeta/actions/workflows/R-CMD-check.yaml)
[](https://cran.r-project.org/package=ncmeta)
[](https://cran.r-project.org/package=ncmeta)
# ncmeta
The `ncmeta` package provides straightforward NetCDF metadata, with a
set of consistent entity-based functions for extracting metadata from a
file or online source. We aim to fill a gap in between the generality
and power of the NetCDF framework and ease of use.
There are two main packages for using NetCDF in R, `RNetCDF` and `ncdf4`
and ncmeta uses both, where appropriate. Both packages are very close
the native API of NetCDF itself, and ncmeta simply provides an easier
high-level interpretation.
## About NetCDF
NetCDF is both a data model and an API, and provides a very general
framework for expressing data formats. The explicit entities in NetCDF
are **variables**, **dimensions** and **attributes** and ncmeta provides
functions `nc_vars`, `nc_dims`, and `nc_atts` to extract their names,
order and other metadata. There are matching functions `nc_var`,
`nc_dim`, and `nc_att` with an extra identifier to extract specific
information about an individual variable, dimension, or attribute.
Also includes functions for implicit entities, these are **grids** and
**axes**. These don’t exist in the NetCDF specification explicitly, but
are meaningful and worth making explicit. Many NetCDF tools don’t
explicitly present these concepts so grab hold of them with ncmeta!
A **grid** is an ordered set of dimensions, and the [Unidata
site](https://www.unidata.ucar.edu/software/netcdf/) refers *informally*
to this concept as **shape**.
An **axis** is an *instance* of a dimension, the use of that dimension
within a particular variable.
These functions provide a more developer-friendly scheme for working
with the range of formats provided by the NetCDF ecosystem.
## Installation
Install ncmeta from CRAN with:
``` r
install.packages("ncmeta")
```
You can install the development version of ncmeta from github with:
``` r
# install.packages("devtools")
devtools::install_github("hypertidy/ncmeta")
```
## Example
This example shows some of the functions for extracting information from
a NetCDF source.
``` r
library(ncmeta)
filename <- system.file("extdata", "S2008001.L3m_DAY_CHL_chlor_a_9km.nc", package = "ncmeta")
nc_inq(filename) # one-row summary of file
nc_dim(filename, 0) ## first dimension
nc_dims(filename) ## all dimensions
```
## Get involved!
Please let us know if you have any feedback, see the [Issues
tab](https://github.com/hypertidy/ncmeta) if you found a bug or have a
question. Feel free to email the maintainer directly for other
questions.
------------------------------------------------------------------------
Please note that this project is released with a [Contributor Code of
Conduct](https://github.com/hypertidy/ncmeta/blob/master/CODE_OF_CONDUCT.md#contributor-code-of-conduct).
By participating in this project you agree to abide by its terms.
ncmeta/man/ 0000755 0001762 0000144 00000000000 14520356651 012303 5 ustar ligges users ncmeta/man/nc_dims.Rd 0000644 0001762 0000144 00000001004 14520356511 014174 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/nc_dimension.R
\name{nc_dims}
\alias{nc_dims}
\alias{nc_dims.character}
\alias{nc_dims.NetCDF}
\alias{nc_dims.ncdf4}
\title{NetCDF dimension}
\usage{
nc_dims(x, ...)
\method{nc_dims}{character}(x, ...)
\method{nc_dims}{NetCDF}(x, ...)
\method{nc_dims}{ncdf4}(x, ...)
}
\arguments{
\item{x}{file address or handle}
\item{...}{ignored}
}
\description{
Get information about the dimensions in a NetCDF source.
}
ncmeta/man/nc_coord_var.Rd 0000644 0001762 0000144 00000003171 14520356511 015225 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/nc_coord.R
\name{nc_coord_var}
\alias{nc_coord_var}
\alias{nc_coord_var.character}
\alias{nc_coord_var.NetCDF}
\title{Get Coordinate Variables for Given Variable}
\usage{
nc_coord_var(x, variable = NULL, ...)
\method{nc_coord_var}{character}(x, variable = NULL, ...)
\method{nc_coord_var}{NetCDF}(x, variable = NULL, ...)
}
\arguments{
\item{x}{NetCDF source}
\item{variable}{variable name of interest.
If not included, all variables will be returned.}
\item{...}{ignored}
}
\value{
tibble with "variable", "X", "Y", "Z", "T", and "bounds" columns that reference
variables by name.
}
\description{
In NetCDF, variables are defined along dimensions and are said to have "coordinate
variables" that define the (typically spatio-temporal) positions of the data's cells.
}
\details{
This function attempts to identify the X, Y, Z, and T coordinate variables for each
data variable in the provided NetCDF source. The NetCDF-CF attribute conventions are
used to make this determination.
All variables that can be related to a spatio-temporal axis, including coordinate
variables are returned. For coordinate variables, a "bounds" column is included in
the response indicating which variable contains bounds information.
See \url{http://cfconventions.org/cf-conventions/v1.6.0/cf-conventions.html#coordinate-system}
for more.
}
\examples{
f <- system.file("extdata", "S2008001.L3m_DAY_CHL_chlor_a_9km.nc", package = "ncmeta")
nc_coord_var(f, "chlor_a")
f <- system.file("extdata", "guam.nc", package = "ncmeta")
nc_coord_var(f)
}
ncmeta/man/nc_inq.Rd 0000644 0001762 0000144 00000001443 14520356511 014036 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/nc_inq_file.R
\name{nc_inq}
\alias{nc_inq}
\alias{nc_inq.NetCDF}
\alias{nc_inq.character}
\title{File info}
\usage{
nc_inq(x, ...)
\method{nc_inq}{NetCDF}(x, ...)
\method{nc_inq}{character}(x, ...)
}
\arguments{
\item{x}{filename or handle}
\item{...}{ignored}
}
\description{
Get information about a NetCDF data source, may be a file path, or a \code{RNetCDF}
file handle, or an OpenDAP/Thredds server address.
}
\examples{
\donttest{
\dontrun{
f <- raadfiles:::cmip5_files()$fullname[1]
nc_inq(f)
nc_var(f, 0)
nc_dim(f, 0)
}
}
f <- system.file("extdata", "S2008001.L3m_DAY_CHL_chlor_a_9km.nc", package = "ncmeta")
nc_inq(f)
nc_var(f, 0)
nc_dim(f, 0)
nc_vars(f)
nc_dims(f)
}
ncmeta/man/nc_att.Rd 0000644 0001762 0000144 00000002067 14520356511 014042 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/nc_att.R
\name{nc_att}
\alias{nc_att}
\alias{nc_att.NetCDF}
\alias{nc_att.character}
\title{NetCDF attributes}
\usage{
nc_att(x, variable, attribute, ...)
\method{nc_att}{NetCDF}(x, variable, attribute, ...)
\method{nc_att}{character}(x, variable, attribute, ...)
}
\arguments{
\item{x}{or file handle}
\item{variable}{name or index (zero based) of variable}
\item{attribute}{name or index (zero based) of attribute}
\item{...}{ignored}
}
\value{
data frame of attribute with numeric id, character attribute name,
character or numeric variable id or name depending on input, and attribute value.
}
\description{
Variable attributes are number 0:(n-1). Global attributes are indexed
by -1 or the label "NC_GLOBAL".
}
\details{
\code{nc_inq} includes the number of global attributes
\code{nc_vars} includes the number of variable attributes
}
\examples{
f <- system.file("extdata", "S2008001.L3m_DAY_CHL_chlor_a_9km.nc", package = "ncmeta")
nc_att(f, 0, 0)
}
ncmeta/man/nc_axis.Rd 0000644 0001762 0000144 00000001102 14520356511 014203 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/nc_axis.R
\name{nc_axis}
\alias{nc_axis}
\alias{nc_axis.character}
\alias{nc_axis.NetCDF}
\title{NetCDF axes}
\usage{
nc_axis(x, i)
\method{nc_axis}{character}(x, i)
\method{nc_axis}{NetCDF}(x, i)
}
\arguments{
\item{x}{NetCDF source}
\item{i}{index of axis (1-based, 0 is "empty")}
}
\description{
An \code{axis} is an instance of a dimension.
}
\details{
Each data source has a set of dimensions available for use by variables. Each axis is
a 1-dimensional instance.
}
ncmeta/man/nc_grid_mapping_atts.Rd 0000644 0001762 0000144 00000002133 14520356511 016737 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/nc-gridmapping.R
\name{nc_grid_mapping_atts}
\alias{nc_grid_mapping_atts}
\alias{nc_grid_mapping_atts.character}
\alias{nc_grid_mapping_atts.NetCDF}
\alias{nc_grid_mapping_atts.data.frame}
\title{Get Grid Mapping}
\usage{
nc_grid_mapping_atts(x, data_variable = NULL)
\method{nc_grid_mapping_atts}{character}(x, data_variable = NULL)
\method{nc_grid_mapping_atts}{NetCDF}(x, data_variable = NULL)
\method{nc_grid_mapping_atts}{data.frame}(x, data_variable = NULL)
}
\arguments{
\item{x}{open NetCDF object, character file path or url to be
opened with RNetCDF::open.nc, or data.frame as returned from ncmeta::nc_atts}
\item{data_variable}{character variable of interest}
}
\value{
tibble containing attributes that make up the file's grid_mapping.
A data_variable column is included to indicate which data variable the grid
mapping belongs to.
}
\description{
Get the grid mapping from a NetCDF file
}
\examples{
nc_grid_mapping_atts(system.file("extdata/daymet_sample.nc", package = "ncmeta"))
}
ncmeta/man/ncmeta-package.Rd 0000644 0001762 0000144 00000005645 14520356651 015444 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/ncmeta-package.r
\docType{package}
\name{ncmeta-package}
\alias{ncmeta}
\alias{ncmeta-package}
\title{ncmeta: Straightforward 'NetCDF' Metadata}
\description{
Extract metadata from 'NetCDF' data sources, these can be files, file handles or servers. This package leverages and extends the lower level functions of the 'RNetCDF' package providing a consistent set of functions that all return data frames. We introduce named concepts of 'grid', 'axis' and 'source' which are all meaningful entities without formal definition in the 'NetCDF' library \url{https://www.unidata.ucar.edu/software/netcdf/}. 'RNetCDF' matches the library itself with only the named concepts of 'variables', 'dimensions' and 'attributes'.
\code{ncmeta} provides a consistent set of tools to obtain metadata from NetCDF. NetCDF
is 'Network Common Data Form' https://www.unidata.ucar.edu/software/netcdf/.
These functions are generics, allowing methods to be written for various providers so that
everything can work from a common basis. All functions return a data frame.
}
\details{
Each function responds to a character file name or data source (i.e. URL) or to a connection of a
given class, this is so a source connection may be created a minimal number of times and kept open
while a number of entities are queried.
Each "given" entity may be referred to by index (0-based) or name, just as it would be by the NetCDF
API and by the two R wrapper providers \code{RNetCDF} and \code{ncdf4}.
\tabular{ll}{
\code{\link{nc_att}} \tab find the given attribute of a given variable \cr
\code{\link{nc_atts}} \tab find all attributes, of all variables and globals \cr
\code{\link{nc_axes}} \tab find all the instances of dimensions \cr
\code{\link{nc_axis}} \tab find given instance of a dimension (1-based) \cr
\code{\link{nc_dim}} \tab find the given dimension of a source (0-based) \cr
\code{\link{nc_dims}} \tab find all the dimensions of a source \cr
\code{\link{nc_grids}} \tab find the grids (sets of dimensions) of a source \cr
\code{\link{nc_inq}} \tab inquire about a source (i.e. number of dimensions, number of variables, number of global attributes and presence of unlimited dimension \cr
\code{\link{nc_meta}} \tab find all metadata for a source (runs all other functions) \cr
\code{\link{nc_sources}} \tab tags a record of a source and its "access time" \cr
\code{\link{nc_var}} \tab find a given variable (0-based) \cr
\code{\link{nc_vars}} \tab find the variables of a source \cr
}
}
\seealso{
Useful links:
\itemize{
\item \url{https://github.com/hypertidy/ncmeta}
\item Report bugs at \url{https://github.com/hypertidy/ncmeta/issues}
}
}
\author{
\strong{Maintainer}: Michael Sumner \email{mdsumner@gmail.com}
Other contributors:
\itemize{
\item Tomas Remenyi [contributor]
\item Ben Raymond [contributor]
\item David Blodgett [contributor]
\item Milton Woods [contributor]
}
}
\keyword{internal}
ncmeta/man/nc_gm_to_prj.Rd 0000644 0001762 0000144 00000002402 14520356511 015223 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/nc-prj.R
\name{nc_gm_to_prj}
\alias{nc_gm_to_prj}
\alias{nc_gm_to_prj.data.frame}
\alias{nc_gm_to_prj.list}
\title{Get projection from NetCDF-CF Grid Mapping}
\usage{
nc_gm_to_prj(x)
\method{nc_gm_to_prj}{data.frame}(x)
\method{nc_gm_to_prj}{list}(x)
}
\arguments{
\item{x}{list or data.frame of attributes of the grid mapping variable
as returned by ncdf or ncdf4's get attributes functions or ncmeta's nc_grid_mapping_atts.}
}
\value{
A proj4 string.
}
\description{
Takes NetCDF-CF grid mapping attributes and returns
a proj4 string.
}
\details{
The WGS84 datum is used as a default if one os not provided
in the grid mapping.
If only a semi_major axis is provided, a sperical earth is assumed.
}
\examples{
crs <- list(grid_mapping_name="latitude_longitude",
longitude_of_prime_meridian = 0,
semi_major_axis = 6378137,
inverse_flattening = 298)
nc_gm_to_prj(crs)
}
\references{
\enumerate{
\item \url{https://en.wikibooks.org/wiki/PROJ.4}
\item \url{https://trac.osgeo.org/gdal/wiki/NetCDF_ProjectionTestingStatus}
\item \url{http://cfconventions.org/cf-conventions/cf-conventions.html#appendix-grid-mappings}
}
}
ncmeta/man/nc_sources.Rd 0000644 0001762 0000144 00000000623 14520356511 014731 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/nc_sources.R
\name{nc_sources}
\alias{nc_sources}
\alias{nc_sources.character}
\title{NetCDF sources}
\usage{
nc_sources(x, ...)
\method{nc_sources}{character}(x, ...)
}
\arguments{
\item{x}{data source string}
\item{...}{ignored}
}
\description{
A record of file, URL, or any data source with NetCDF.
}
ncmeta/man/nc_var.Rd 0000644 0001762 0000144 00000001152 14520356511 014034 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/nc_var.R
\name{nc_var}
\alias{nc_var}
\alias{nc_var.character}
\alias{nc_var.NetCDF}
\title{NetCDF variable}
\usage{
nc_var(x, i)
\method{nc_var}{character}(x, i)
\method{nc_var}{NetCDF}(x, i)
}
\arguments{
\item{x}{file name or handle}
\item{i}{variable index (zero based)}
}
\value{
data frame of variable information
}
\description{
Return a data frame about the variable at index \code{i}.
}
\seealso{
\code{nc_vars} to obtain information about all variables, \code{nc_inq} for an
overview of the file
}
ncmeta/man/nc_dim.Rd 0000644 0001762 0000144 00000001345 14520356511 014021 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/nc_dim.R
\name{nc_dim}
\alias{nc_dim}
\alias{nc_dim.character}
\alias{nc_dim.NetCDF}
\alias{nc_dim.ncdf4}
\title{NetCDF variables
Obtain information about a single dimension by index.}
\usage{
nc_dim(x, i, ...)
\method{nc_dim}{character}(x, i, ...)
\method{nc_dim}{NetCDF}(x, i, ...)
\method{nc_dim}{ncdf4}(x, i, ...)
}
\arguments{
\item{x}{filename or handle}
\item{i}{index of dimension (zero based)}
\item{...}{ignored}
}
\description{
NetCDF variables
Obtain information about a single dimension by index.
}
\seealso{
\code{nc_vars} to obtain information about all dimensions, \code{nc_inq} for an
overview of the file
}
ncmeta/man/nc_prj_to_gridmapping.Rd 0000644 0001762 0000144 00000002243 14520356511 017124 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/nc-gridmapping.R
\name{nc_prj_to_gridmapping}
\alias{nc_prj_to_gridmapping}
\title{Get NetCDF-CF grid mapping from projection}
\usage{
nc_prj_to_gridmapping(prj)
}
\arguments{
\item{prj}{character PROJ string as used in raster, sf, sp, proj4, and rgdal packages.}
}
\value{
A named list containing attributes required for that grid_mapping.
}
\description{
Takes a proj4 string and returns a NetCDF-CF projection as
a named list of attributes.
}
\examples{
prj <- "+proj=longlat +datum=NAD27 +no_defs"
nc_prj_to_gridmapping(prj)
p1 <- "+proj=aea +lat_1=29.5 +lat_2=45.5 +lat_0=23 +lon_0=-96"
p2 <- "+x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs"
prj2 <- sprintf("\%s \%s", p1, p2)
nc_prj_to_gridmapping(prj2)
nc_prj_to_gridmapping("+proj=longlat +a=6378137 +f=0.00335281066474748 +pm=0 +no_defs")
}
\references{
\enumerate{
\item \url{https://en.wikibooks.org/wiki/PROJ.4}
\item \url{https://trac.osgeo.org/gdal/wiki/NetCDF_ProjectionTestingStatus}
\item \url{http://cfconventions.org/cf-conventions/cf-conventions.html#appendix-grid-mappings}
}
}
ncmeta/man/nc_vars.Rd 0000644 0001762 0000144 00000000751 14520356511 014223 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/nc_variable.R
\name{nc_vars}
\alias{nc_vars}
\alias{nc_vars.character}
\alias{nc_vars.NetCDF}
\title{NetCDF variables}
\usage{
nc_vars(x, ...)
\method{nc_vars}{character}(x, ...)
\method{nc_vars}{NetCDF}(x, ...)
}
\arguments{
\item{x}{filename or handle}
\item{...}{ignored currently}
}
\value{
data frame of variable information
}
\description{
Generate a table of all variables.
}
ncmeta/man/nc_atts.Rd 0000644 0001762 0000144 00000001576 14520356511 014231 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/nc_att.R
\name{nc_atts}
\alias{nc_atts}
\alias{nc_atts.NetCDF}
\alias{nc_atts.character}
\title{NetCDF attributes}
\usage{
nc_atts(x, variable = NULL, ...)
\method{nc_atts}{NetCDF}(x, variable = NULL, ...)
\method{nc_atts}{character}(x, variable = NULL, ...)
}
\arguments{
\item{x}{filename or handle}
\item{variable}{optional single name of a variable, or 'NC_GLOBAL'}
\item{...}{ignored}
}
\value{
data frame of attributes
}
\description{
All attributes in the file, globals are treated as if they belong to variable 'NC_GLOBAL'. Attributes
for a single variable may be returned by specifying 'variable' - 'NC_GLOBAL' can stand in to return
only those attributes.
}
\examples{
f <- system.file("extdata", "S2008001.L3m_DAY_CHL_chlor_a_9km.nc", package = "ncmeta")
nc_atts(f)
}
ncmeta/man/nc_axes.Rd 0000644 0001762 0000144 00000001216 14520356511 014205 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/nc_axes.R
\name{nc_axes}
\alias{nc_axes}
\alias{nc_axes.character}
\alias{nc_axes.NetCDF}
\title{NetCDF axes}
\usage{
nc_axes(x, variables = NULL, ...)
\method{nc_axes}{character}(x, variables = NULL, ...)
\method{nc_axes}{NetCDF}(x, variables = NULL, ...)
}
\arguments{
\item{x}{NetCDF source}
\item{variables}{names of vars to query}
\item{...}{ignored}
}
\description{
An \code{axis} is an instance of a dimension.
}
\details{
Each data source has a set of dimensions available for use by variables. Each axis is
a 1-dimensional instance.
}
ncmeta/man/nc_grids.Rd 0000644 0001762 0000144 00000002210 14520356511 014350 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/nc_grid.R, R/tidync.R
\name{nc_grids}
\alias{nc_grids}
\alias{nc_grids.character}
\alias{nc_grids.NetCDF}
\alias{nc_grids.tidync}
\title{NetCDF grids}
\usage{
nc_grids(x, ...)
\method{nc_grids}{character}(x, ...)
\method{nc_grids}{NetCDF}(x, ...)
\method{nc_grids}{tidync}(x, ...)
}
\arguments{
\item{x}{NetCDF source}
\item{...}{ignored}
}
\description{
A \code{grid} is a discretized space, defined by a set of dimensions. These are the spaces used
by one or more variables in a source. Traditional summaries are organized by variable, but
when organized by space or grid we can treat multiple variables together using standard
database techniques.
}
\details{
Each data source has a set of dimensions available for use by variables. Each grid is
an n-dimensional space available for use by 0, 1 or more variables. A grid only really
exists if variable is defined for it, and 'grid' is an implicit entity not an explicit
part of the NetCDF API definition. The Unidata pages refer to "shape", which is more or less what
we mean by "grid".
}
ncmeta/man/nc_meta.Rd 0000644 0001762 0000144 00000002027 14520356511 014174 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/nc_meta.R
\name{nc_meta}
\alias{nc_meta}
\alias{nc_meta.NetCDF}
\alias{nc_meta.character}
\title{Top level NetCDF metadata.}
\usage{
nc_meta(x, ...)
\method{nc_meta}{NetCDF}(x, ...)
\method{nc_meta}{character}(x, ...)
}
\arguments{
\item{x}{data source address, file name or handle}
\item{...}{ignored}
}
\description{
This function exists to maintain the open connection
while all dimension, variable, and attribute metadata is extracted.
}
\details{
This function is pretty ambitious, and will send nearly any string
to the underlying NetCDF library other than "", which immediately
generates an error. This should be robust, but might present fairly
obscure error messages from the underlying library.
}
\examples{
f <- system.file("extdata", "S2008001.L3m_DAY_CHL_chlor_a_9km.nc", package = "ncmeta")
nc_meta(f)
\donttest{
\dontrun{
u <- "https://upwell.pfeg.noaa.gov/erddap/tabledap/FRDCPSTrawlLHHaulCatch"
nc_meta(u)
}}
}
ncmeta/DESCRIPTION 0000644 0001762 0000144 00000002757 14520367022 013243 0 ustar ligges users Package: ncmeta
Title: Straightforward 'NetCDF' Metadata
Version: 0.3.6
Authors@R: c(person("Michael", "Sumner", email = "mdsumner@gmail.com", role = c("aut", "cre")),
person("Tomas", "Remenyi", role = "ctb"),
person("Ben", "Raymond", role = "ctb"),
person("David", "Blodgett", role = "ctb"),
person("Milton", "Woods", role = "ctb"))
Description: Extract metadata from 'NetCDF' data sources, these can be files, file handles or
servers. This package leverages and extends the lower level functions of the 'RNetCDF' package
providing a consistent set of functions that all return data frames. We introduce named concepts
of 'grid', 'axis' and 'source' which are all meaningful entities without formal definition in the
'NetCDF' library . 'RNetCDF' matches the library
itself with only the named concepts of 'variables', 'dimensions' and 'attributes'.
Depends: R (>= 3.3.0)
License: GPL-3
Encoding: UTF-8
RoxygenNote: 7.2.3
Imports: dplyr, rlang, RNetCDF, tibble, stats, tidyr
Suggests: testthat, covr
URL: https://github.com/hypertidy/ncmeta
BugReports: https://github.com/hypertidy/ncmeta/issues
ByteCompile: TRUE
NeedsCompilation: no
Packaged: 2023-11-01 05:46:46 UTC; gdal
Author: Michael Sumner [aut, cre],
Tomas Remenyi [ctb],
Ben Raymond [ctb],
David Blodgett [ctb],
Milton Woods [ctb]
Maintainer: Michael Sumner
Repository: CRAN
Date/Publication: 2023-11-01 06:20:02 UTC
ncmeta/tests/ 0000755 0001762 0000144 00000000000 14520356511 012665 5 ustar ligges users ncmeta/tests/testthat/ 0000755 0001762 0000144 00000000000 14520367022 014524 5 ustar ligges users ncmeta/tests/testthat/test-attributes.R 0000644 0001762 0000144 00000007155 14520356511 020023 0 ustar ligges users context("attributes")
f <- system.file("extdata", "S2008001.L3m_DAY_CHL_chlor_a_9km.nc", package = "ncmeta")
u <- "https://upwell.pfeg.noaa.gov/erddap/tabledap/FRDCPSTrawlLHHaulCatch"
test_that("attributes works", {
testthat::skip_on_cran()
met <- nc_meta(f)
da <- nc_atts(f) %>% expect_s3_class("tbl_df") %>%
expect_named(c("id", "name", "variable", "value"))
expect_that(nrow(da), equals(87L))
expect_that(da$value, is_a("list"))
da <- nc_atts(f, add_names = TRUE) %>% expect_s3_class("tbl_df") %>%
expect_named(c("id", "name", "variable", "value"))
})
test_that("attributes from Thredds works", {
context("avoiding thredds tests for RNetCDF")
skip_on_cran()
## skip() ## github can't do this atm 2022-08-15
du <- try(nc_atts(u))
if (!inherits(du, "try-error")) {
du %>% expect_s3_class("tbl_df") %>%
expect_named(c("id", "name", "variable", "value"))
# expect_that(nrow(du), equals(119L)) ## became 124 rows in 2022 August
expect_that(du$value, is_a("list"))
}
})
test_that("individual attribute inquiry works", {
testthat::skip_on_cran()
nc_att(f, 0, 0) %>% expect_s3_class("tbl_df") %>%
expect_named(c("id", "name", "variable", "value"))
a3 <- nc_att(f, 0, 3)
expect_that(a3$id, equals(3.0))
expect_that(a3$name, equals("_FillValue"))
chk <- list(`_FillValue` = -32767)
expect_that(a3$value, equals(chk))
expect_identical(a3, nc_att(f, 0, "_FillValue"))
})
l3binfile <- system.file("extdata", "S2008001.L3b_DAY_CHL.nc", package = "ncmeta")
test_that("failure is graceful", {
expect_warning(abin <- nc_atts(l3binfile), "no variables recognizable")
abin %>% expect_s3_class("tbl_df") %>%
expect_named(c("id", "name", "variable", "value"))
expect_that(nrow(abin), equals(49L))
expect_that(abin$variable, equals(rep("NC_GLOBAL",49L)))
expect_that(abin$name, equals(c("product_name", "title", "instrument", "platform", "temporal_range",
"start_orbit_number", "end_orbit_number", "date_created", "processing_version",
"history", "time_coverage_start", "time_coverage_end", "northernmost_latitude",
"southernmost_latitude", "easternmost_longitude", "westernmost_longitude",
"geospatial_lat_max", "geospatial_lat_min", "geospatial_lon_max",
"geospatial_lon_min", "geospatial_lat_units", "geospatial_lon_units",
"geospatial_lon_resolution", "geospatial_lat_resolution", "spatialResolution",
"data_bins", "percent_data_bins", "units", "binning_scheme",
"project", "institution", "standard_name_vocabulary", "Metadata_Conventions",
"Conventions", "naming_authority", "id", "license", "creator_name",
"publisher_name", "creator_email", "publisher_email", "creator_url",
"publisher_url", "processing_level", "cdm_data_type", "identifier_product_doi_authority",
"identifier_product_doi", "keywords", "keywords_vocabulary")))
expect_that(unique(abin$id), equals(-1))
})
test_that("nc_atts works", {
## https://github.com/hypertidy/ncmeta/issues/36
f <- system.file("extdata", "S2008001.L3m_DAY_CHL_chlor_a_9km.nc", package = "ncmeta")
expect_equal(nc_atts(f, "NC_GLOBAL")$variable, rep("NC_GLOBAL", 65))
expect_equal(nrow(nc_atts(f)), 87)
expect_equal(nrow(nc_atts(f, "chlor_a")), 12)
expect_equal(nrow(nc_atts(f, "lon")), 5)
})
ncmeta/tests/testthat/test-gridmapping-prj.R 0000644 0001762 0000144 00000041134 14520356511 020722 0 ustar ligges users context("prj and grid mappings")
test_that("nc_grid_mapping_atts", {
nc <- system.file("extdata/S2008001.L3m_DAY_CHL_chlor_a_9km.nc", package = "ncmeta")
expect_warning(gm <- nc_grid_mapping_atts(nc),
paste("No variables with a grid mapping found.\n",
"Defaulting to WGS84 Lon/Lat"))
expect_equal(stats::setNames(gm$value, gm$name), list(grid_mapping_name = "latitude_longitude",
semi_major_axis = 6378137,
inverse_flattening = 298.257223563,
longitude_of_prime_meridian = 0))
nc <- system.file("extdata/daymet_sample.nc", package = "ncmeta")
gm <- nc_grid_mapping_atts(nc)
expect_true(all(list(grid_mapping_name = "lambert_conformal_conic",
longitude_of_central_meridian = -100,
latitude_of_projection_origin = 42.5,
false_easting = 0,
false_northing = 0,
standard_parallel = c(25, 60),
semi_major_axis = 6378137,
inverse_flattening = 298.257223563,
longitude_of_prime_meridian = 0) %in% stats::setNames(gm$value, gm$name)))
expect_is(nc_grid_mapping_atts(ncmeta::nc_atts(nc)), "data.frame")
expect_is(nc_grid_mapping_atts(RNetCDF::open.nc(nc)), "data.frame")
gm2 <- nc_grid_mapping_atts(nc, data_variable = "prcp")
expect_equal(nrow(gm), nrow(gm2))
expect_warning(nc_grid_mapping_atts(nc, data_variable = "borked"),
"no grid_mapping attribute found for this variable")
})
test_that("nc_prj_to_gridmapping returns an empty list if no mapping exists", {
p <- ""
expect_warning(crs <- nc_prj_to_gridmapping(p),
"not a valid crs, returning an empty tibble")
expect_equal(names(crs), c("name", "value"))
expect_equal(nrow(crs), 0)
})
test_that("wgs 84 lat lon", {
p <- "+proj=longlat +a=6378137 +f=0.00335281066474748 +pm=0 +no_defs"
c <- list(grid_mapping_name="latitude_longitude",
longitude_of_prime_meridian = 0,
semi_major_axis = 6378137,
inverse_flattening = 298.257223563)
prj <- nc_gm_to_prj(c)
expect_equal(prj, p)
prj <- nc_gm_to_prj(c)
expect_equal(prj, p)
crs <- nc_prj_to_gridmapping(p)
crs <- stats::setNames(crs$value, crs$name)
expect_equal(crs, c[names(crs)])
})
test_that("NAD27 lat lon", {
p <- "+proj=longlat +datum=NAD27 +no_defs"
p2 <- "+proj=longlat +a=6378206.4 +f=0.00339007530392762 +pm=0 +no_defs"
c <- list(grid_mapping_name="latitude_longitude",
longitude_of_prime_meridian = 0,
semi_major_axis = 6378206.4,
inverse_flattening = 294.978698214)
prj <- nc_gm_to_prj(c)
expect_equal(prj, p2)
crs <- nc_prj_to_gridmapping(p)
crs <- stats::setNames(crs$value, crs$name)
expect_equal(crs, c[names(crs)])
})
test_that("albers equal area epsg:5070", {
p <- "+proj=aea +lat_1=29.5 +lat_2=45.5 +x_0=0 +y_0=0 +units=m +lat_0=23 +lon_0=-96 +a=6378137 +f=0.00335281066474748 +pm=0 +no_defs"
c <- list(grid_mapping_name = "albers_conical_equal_area",
longitude_of_central_meridian = -96,
latitude_of_projection_origin = 23,
false_easting = 0.0,
false_northing = 0.0,
standard_parallel = c(29.5, 45.5),
semi_major_axis = 6378137.0,
inverse_flattening = 298.257223563,
longitude_of_prime_meridian = 0)
prj <- nc_gm_to_prj(c)
expect_equal(prj, p)
crs <- nc_prj_to_gridmapping(p)
crs <- stats::setNames(crs$value, crs$name)
expect_equal(crs, c[names(crs)])
})
test_that("albers equal area epsg:5070 with datum instead of a b", {
p <- "+proj=aea +lat_1=29.5 +lat_2=45.5 +lat_0=23 +lon_0=-96 +x_0=0 +y_0=0 +units=m +datum=NAD83 +units=m +no_defs +ellps=GRS80 +towgs84=0,0,0"
c <- list(grid_mapping_name = "albers_conical_equal_area",
longitude_of_central_meridian = -96,
latitude_of_projection_origin = 23,
false_easting = 0.0,
false_northing = 0.0,
standard_parallel = c(29.5, 45.5),
semi_major_axis = 6378137.0,
inverse_flattening = 298.257222101,
longitude_of_prime_meridian = 0)
crs <- nc_prj_to_gridmapping(p)
crs <- stats::setNames(crs$value, crs$name)
expect_equal(crs, c[names(crs)])
})
test_that("Azimuthal Equidistant", {
p <- "+proj=aeqd +lat_0=30 +lon_0=-40 +x_0=0 +y_0=0 +units=m +a=6378137 +f=0.00335281066474748 +pm=0 +no_defs"
c <- list(grid_mapping_name = "azimuthal_equidistant",
longitude_of_projection_origin = -40,
latitude_of_projection_origin = 30,
false_easting = 0.0,
false_northing = 0.0,
longitude_of_prime_meridian = 0.0,
semi_major_axis = 6378137.0,
inverse_flattening = 298.257223563)
prj <- nc_gm_to_prj(c)
expect_equal(prj, p)
crs <- nc_prj_to_gridmapping(p)
crs <- stats::setNames(crs$value, crs$name)
expect_equal(crs[names(c)], c)
})
test_that("lambert conformal conic daymet", {
p <- "+proj=lcc +lat_1=25 +lat_2=60 +x_0=0 +y_0=0 +units=m +lat_0=42.5 +lon_0=-100 +a=6378137 +f=0.00335281066474748 +pm=0 +no_defs"
c <- list(grid_mapping_name = "lambert_conformal_conic",
longitude_of_central_meridian = -100.0,
latitude_of_projection_origin = 42.5,
false_easting = 0.0,
false_northing = 0.0,
standard_parallel = c(25.0, 60.0),
longitude_of_prime_meridian = 0.0,
semi_major_axis = 6378137.0,
inverse_flattening = 298.257223563)
prj <- nc_gm_to_prj(c)
expect_equal(prj, p)
crs <- nc_prj_to_gridmapping(p)
crs <- stats::setNames(crs$value, crs$name)
expect_equal(crs[names(c)], c)
})
test_that("lambert_azimuthal_equal_area", {
p <- "+proj=laea +lat_0=90 +lon_0=0 +x_0=0 +y_0=0 +units=m +a=6371228 +b=6371228 +pm=0 +no_defs"
c <- list(grid_mapping_name = "lambert_azimuthal_equal_area",
longitude_of_projection_origin = 0,
latitude_of_projection_origin = 90,
false_easting = 0.0,
false_northing = 0.0,
semi_major_axis = 6371228,
semi_minor_axis = 6371228,
longitude_of_prime_meridian = 0.0)
prj <- nc_gm_to_prj(c)
expect_equal(prj, p)
crs <- nc_prj_to_gridmapping(p)
crs <- stats::setNames(crs$value, crs$name)
c <- list(grid_mapping_name = "lambert_azimuthal_equal_area",
longitude_of_projection_origin = 0,
latitude_of_projection_origin = 90,
false_easting = 0.0,
false_northing = 0.0,
longitude_of_prime_meridian = 0.0,
semi_major_axis = 6371228)
prj <- nc_gm_to_prj(c)
expect_equal(prj, p)
crs <- nc_prj_to_gridmapping(p)
crs <- stats::setNames(crs$value, crs$name)
expect_equal(crs[names(c)], c)
})
test_that("lambert_cylindrical_equal_area", {
p <- "+proj=cea +lon_0=0 +lat_ts=0 +x_0=0 +y_0=0 +units=m +a=6378137 +f=0.00335281066474748 +pm=0 +no_defs"
c <- list(grid_mapping_name = "lambert_cylindrical_equal_area",
longitude_of_central_meridian = 0,
standard_parallel=0,
false_easting = 0.0,
false_northing = 0.0,
longitude_of_prime_meridian = 0.0,
semi_major_axis = 6378137.0,
inverse_flattening = 298.257223563)
prj <- nc_gm_to_prj(c)
expect_equal(prj, p)
crs <- nc_prj_to_gridmapping(p)
crs <- stats::setNames(crs$value, crs$name)
expect_equal(crs[names(c)], c)
})
test_that("mercator", {
p <- "+proj=merc +lon_0=0 +lat_ts=0 +x_0=0 +y_0=0 +units=m +a=6378137 +f=0.00335281066474748 +pm=0 +no_defs"
c <- list(grid_mapping_name = "mercator",
longitude_of_projection_origin = 0,
standard_parallel=0,
false_easting = 0.0,
false_northing = 0.0,
longitude_of_prime_meridian = 0.0,
semi_major_axis = 6378137.0,
inverse_flattening = 298.257223563)
prj <- nc_gm_to_prj(c)
expect_equal(prj, p)
crs <- nc_prj_to_gridmapping(p)
crs <- stats::setNames(crs$value, crs$name)
expect_equal(crs[names(c)], c)
p <- "+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +units=m +a=6378137 +f=0.00335281066474748 +pm=0 +no_defs"
c <- list(grid_mapping_name = "mercator",
longitude_of_projection_origin = 0,
scale_factor_at_projection_origin=1,
false_easting = 0.0,
false_northing = 0.0,
longitude_of_prime_meridian = 0.0,
semi_major_axis = 6378137.0,
inverse_flattening = 298.257223563)
prj <- nc_gm_to_prj(c)
expect_equal(prj, p)
crs <- nc_prj_to_gridmapping(p)
crs <- stats::setNames(crs$value, crs$name)
expect_equal(crs[names(c)], c)
})
test_that("oblique_mercator", {
p <- "+proj=omerc +lat_0=45.3091666666667 +lonc=-86 +k=0.9996 +alpha=337.25556 +gamma=337.25556 +no_uoff +x_0=2546731.496 +y_0=-4354009.816 +units=m +a=6378137 +f=0.00335281066474748 +pm=0 +no_defs"
c <- list(grid_mapping_name = "oblique_mercator",
azimuth_of_central_line = 337.25556,
longitude_of_projection_origin = -86,
latitude_of_projection_origin = 45.3091666666667,
scale_factor_at_projection_origin = 0.9996,
false_easting = 2546731.496,
false_northing = -4354009.816,
longitude_of_prime_meridian = 0.0,
semi_major_axis = 6378137.0,
inverse_flattening = 298.257223563)
prj <- nc_gm_to_prj(c)
expect_equal(prj, p)
crs <- nc_prj_to_gridmapping(p)
crs <- stats::setNames(crs$value, crs$name)
expect_equal(crs[names(c)], c)
})
test_that("orthographic", {
p <- "+proj=ortho +lat_0=30 +lon_0=-40 +x_0=0 +y_0=0 +units=m +a=6378137 +f=0.00335281066474748 +pm=0 +no_defs"
c <- list(grid_mapping_name = "orthographic",
longitude_of_projection_origin = -40,
latitude_of_projection_origin = 30,
false_easting = 0.0,
false_northing = 0.0,
longitude_of_prime_meridian = 0.0,
semi_major_axis = 6378137.0,
inverse_flattening = 298.257223563)
prj <- nc_gm_to_prj(c)
expect_equal(prj, p)
crs <- nc_prj_to_gridmapping(p)
crs <- stats::setNames(crs$value, crs$name)
expect_equal(crs[names(c)], c)
})
test_that("polar_stereographic", {
p <- "+proj=stere +lat_0=-90 +lon_0=0 +k=1 +x_0=0 +y_0=0 +units=m +a=6378137 +f=0.00335281066474748 +pm=0 +no_defs"
c <- list(grid_mapping_name = "polar_stereographic",
straight_vertical_longitude_from_pole = 0,
latitude_of_projection_origin = -90,
scale_factor_at_projection_origin = 1,
false_easting = 0.0,
false_northing = 0.0,
longitude_of_prime_meridian = 0.0,
semi_major_axis = 6378137.0,
inverse_flattening = 298.257223563)
prj <- nc_gm_to_prj(c)
expect_equal(prj, p)
# crs <- nc_prj_to_gridmapping(p)
# crs <- stats::setNames(crs$value, crs$name)
#
# expect_equal(crs[names(c)], c)
p <- "+proj=stere +lat_0=-90 +lon_0=0 +lat_ts=-71 +x_0=0 +y_0=0 +units=m +a=6378137 +f=0.00335281066474748 +pm=0 +no_defs"
c <- list(grid_mapping_name = "polar_stereographic",
straight_vertical_longitude_from_pole = 0,
latitude_of_projection_origin = -90,
standard_parallel = -71,
false_easting = 0.0,
false_northing = 0.0,
longitude_of_prime_meridian = 0.0,
semi_major_axis = 6378137.0,
inverse_flattening = 298.257223563)
prj <- nc_gm_to_prj(c)
expect_equal(prj, p)
# crs <- nc_prj_to_gridmapping(p)
# crs <- stats::setNames(crs$value, crs$name)
#
# expect_equal(crs[names(c)], c)
})
test_that("sinusoidal", {
p <- "+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +units=m +a=6378137 +f=0.00335281066474748 +pm=0 +no_defs"
c <- list(grid_mapping_name = "sinusoidal",
longitude_of_projection_origin = 0,
false_easting = 0.0,
false_northing = 0.0,
longitude_of_prime_meridian = 0.0,
semi_major_axis = 6378137.0,
inverse_flattening = 298.257223563)
prj <- nc_gm_to_prj(c)
expect_equal(prj, p)
})
test_that("stereographic", {
p <- "+proj=stere +lat_0=46.5 +lon_0=-66.5 +k=0.999912 +x_0=2500000 +y_0=7500000 +units=m +a=6378137 +f=0.00335281066474748 +pm=0 +no_defs"
c <- list(grid_mapping_name = "stereographic",
longitude_of_projection_origin = -66.5,
latitude_of_projection_origin = 46.5,
scale_factor_at_projection_origin = 0.999912,
false_easting = 2500000,
false_northing = 7500000,
longitude_of_prime_meridian = 0.0,
semi_major_axis = 6378137.0,
inverse_flattening = 298.257223563)
prj <- nc_gm_to_prj(c)
expect_equal(prj, p)
crs <- nc_prj_to_gridmapping(p)
crs <- stats::setNames(crs$value, crs$name)
expect_equal(crs[names(c)], c)
})
test_that("transverse_mercator", {
p <- "+proj=tmerc +lat_0=53.5 +lon_0=-8 +k=0.99982 +x_0=600000 +y_0=750000 +units=m +a=6378137 +f=0.00335281066474748 +pm=0 +no_defs"
c <- list(grid_mapping_name = "transverse_mercator",
longitude_of_central_meridian = -8,
latitude_of_projection_origin = 53.5,
scale_factor_at_central_meridian = 0.99982,
false_easting = 600000,
false_northing = 750000,
longitude_of_prime_meridian = 0.0,
semi_major_axis = 6378137.0,
inverse_flattening = 298.257223563)
prj <- nc_gm_to_prj(c)
expect_equal(prj, p)
crs <- nc_prj_to_gridmapping(p)
crs <- stats::setNames(crs$value, crs$name)
expect_equal(crs[names(c)], c)
})
test_that("spherical", {
p <- "+proj=lcc +lat_1=30 +lat_2=60 +x_0=0 +y_0=0 +units=m +lat_0=40.0000076294 +lon_0=-97 +a=6370000 +b=6370000 +pm=0 +no_defs"
# From the National Water Model forcings
cl <- list(transform_name = "lambert_conformal_conic",
grid_mapping_name = "lambert_conformal_conic",
standard_parallel = c(30, 60),
longitude_of_central_meridian = -97,
latitude_of_projection_origin = 40.0000076294,
false_easting = 0,
false_northing = 0,
earth_radius = 6370000)
prj <- suppressWarnings(nc_gm_to_prj(cl))
expect_equal(prj, p)
crs <- nc_prj_to_gridmapping(p)
crs <- stats::setNames(crs$value, crs$name)
expect_equal(crs,
list(grid_mapping_name = "lambert_conformal_conic",
standard_parallel = c(30, 60),
false_easting = 0,
false_northing = 0,
latitude_of_projection_origin = 40.0000076294,
longitude_of_central_meridian = -97,
semi_major_axis = 6370000,
semi_minor_axis = 6370000,
longitude_of_prime_meridian = 0))
})
test_that("more spherical", {
p <- "+proj=lcc +lat_1=30 +lat_2=65 +x_0=-6000 +y_0=-6000 +units=m +lat_0=48 +lon_0=9.75 +a=6371229 +b=6371229 +pm=0 +no_defs"
# from "https://github.com/mdsumner//rasterwise/extdata/EURO-CORDEX_81_DOMAIN000_54/EURO-CORDEX_81_DOMAIN000.nc"
cl <- list(proj4_params = "+proj=lcc +lat_1=30.00 +lat_2=65.00 +lat_0=48.00 +lon_0=9.75 +x_0=-6000. +y_0=-6000. +ellps=sphere +a=6371229. +b=6371229. +units=m +no_defs",
grid_mapping_name = "lambert_conformal_conic",
standard_parallel = c(30, 65),
longitude_of_central_meridian = 9.75,
latitude_of_projection_origin = 48,
semi_major_axis = 6371229,
inverse_flattening = 0, # This is the BS that caused an Inf!
false_easting = -6000,
false_northing = -6000,
`_CoordinateTransformType` = "Projection",
`_CoordinateAxisTypes` = "GeoX GeoY")
prj <- suppressWarnings(nc_gm_to_prj(cl))
expect_equal(prj, p)
crs <- nc_prj_to_gridmapping(p)
crs <- stats::setNames(crs$value, crs$name)
expect_equal(crs,
list(grid_mapping_name = "lambert_conformal_conic",
standard_parallel = c(30, 65),
false_easting = -6000,
false_northing = -6000,
latitude_of_projection_origin = 48,
longitude_of_central_meridian = 9.75,
semi_major_axis = 6371229,
semi_minor_axis = 6371229,
longitude_of_prime_meridian = 0))
})
ncmeta/tests/testthat/test-file-bogatron.R 0000644 0001762 0000144 00000000431 14520356511 020353 0 ustar ligges users # library(testthat)
#
# context("file-bogatron")
# test_that({
# skip_if_not(we_are_raady())
# # sstd1 <- raadtools::sstfiles()$fullname[1]
# # sstm1 <-
# # raadtools::sstfiles(time.resolution = "monthly")$fullname[1]
# # rom1 <- raadtools::cpolarfiles()$fullname[1]
# })
ncmeta/tests/testthat/test-vars.R 0000644 0001762 0000144 00000002373 14520356511 016605 0 ustar ligges users context("vars")
f <- system.file("extdata", "S2008001.L3m_DAY_CHL_chlor_a_9km.nc", package = "ncmeta")
test_that("vars works", {
v <- nc_vars(f)
v %>% expect_s3_class("tbl_df") %>% expect_named(c("id", "name", "type", "ndims", "natts"))
expect_that(v$id, equals(0:3))
expect_that(v$name, equals(c("chlor_a", "lat", "lon", "palette")))
## 2018-02-09
## this test depends on the env, e.g. UNKNOWN on Windows and Mac, UC_BYTE on Ubuntu
## must be RNetCDF version?
# expect_that(v$type, equals(c("NC_FLOAT", "NC_FLOAT", "NC_FLOAT", "NC_UBYTE")))
expect_that(v$ndims, equals(c(2, 1, 1, 2)))
expect_that(v$natts, equals(c(12, 5, 5, 0)))
})
test_that('grids works', {
## FIXME
skip("fixme") ## only in nc-grids-normal branch
g <- nc_grids(f)
s <- nc_sources(f)
v <- nc_var(f, 1)
g %>% expect_s3_class("tbl_df") %>% expect_named(c("variable", "grid"))
s %>% expect_s3_class("tbl_df") %>% expect_named(c("access", "source"))
v %>% expect_s3_class("tbl_df") %>% expect_named(c("id", "name", "type", "ndims", "natts"))
expect_that(g[["variable"]], equals(c("chlor_a", "palette", "lat", "lon")))
})
test_that("nc4 bug", {
f <- system.file("extdata/gridmet_sample.nc", package = "ncmeta")
vars <- nc_vars(f)
expect_equal(nrow(vars), 5)
})
ncmeta/tests/testthat/test-dimension.R 0000644 0001762 0000144 00000002430 14520356511 017611 0 ustar ligges users context("dimension")
f <- system.file("extdata", "S2008001.L3m_DAY_CHL_chlor_a_9km.nc", package = "ncmeta")
test_that("file specific dimension inquiry works", {
dim0 <- nc_dim(f, 0) %>% expect_s3_class("tbl_df")
expect_that(nrow(dim0), equals(1L))
expect_that(dim0$id, equals(0))
expect_that(dim0$name, equals("lat"))
expect_that(dim0$length, equals(2160)) ## double
expect_that(dim0$unlim, equals(FALSE))
# expect_that(unlist(lapply(dim0, typeof)),
# equals(structure(c("integer", "character", "double", "logical"), .Names = c("id",
# "name", "length", "unlim"))))
})
test_that("file all dimensions inquiry works", {
dimension <- nc_dims(f) %>% expect_s3_class("tbl_df")
expect_that(nrow(dimension), equals(4L))
expect_that(dimension$id, equals(0:3))
expect_that(dimension$name, equals(c("lat", "lon", "rgb", "eightbitcolor")))
expect_that(dimension$length, equals(c(2160, 4320, 3, 256))) ## double
expect_false(any(dimension$unlim))
#expect_that(unlist(lapply(dimension, typeof)),
# equals(structure(c("integer", "character", "double", "logical"),
# .Names = c("id","name", "length", "unlim"))))
})
ncmeta/tests/testthat/test-grid-var-order.R 0000644 0001762 0000144 00000000742 14520356511 020454 0 ustar ligges users context("test-grid-var-order")
f <- system.file("extdata/stars/reduced.nc", package= "ncmeta")
test_that("variable order by grid is correct", {
## FIXME
skip("fixme") ## only in nc-grids-normal branch
## descending by ndims, but otherwise native to the source
vars_sort_by_ndims <- nc_vars(f) %>% dplyr::arrange(desc(ndims)) %>% dplyr::pull(name)
expect_equal(nc_meta(f)$grid$variable, vars_sort_by_ndims)
expect_equal(nc_grids(f)$variable, vars_sort_by_ndims)
})
ncmeta/tests/testthat/test-coord.R 0000644 0001762 0000144 00000007030 14520356511 016733 0 ustar ligges users context("nc_coord_var")
f <- system.file("extdata", "S2008001.L3m_DAY_CHL_chlor_a_9km.nc", package = "ncmeta")
nc <- RNetCDF::open.nc(f)
test_that("nc_coord_var brings back expected content for one variable", {
expect_equivalent(nc_coord_var(f, "chlor_a"),
data.frame(variable = "chlor_a", X = "lon", Y = "lat",
Z = NA_character_, T = NA_character_,
bounds = NA_character_,
stringsAsFactors = FALSE))
expect_equal(nc_coord_var(f, "pallete"),
NULL)
expect_equal(nc_coord_var(f, "lat")$Y,
"lat")
})
test_that("nc_coord_vars brings back expected content for sample", {
coord_vars <- nc_coord_var(f)
expect_equivalent(dplyr::filter(coord_vars, variable == "chlor_a"),
data.frame(variable = "chlor_a",
X = "lon", Y = "lat",
Z = NA_character_, T = NA_character_,
bounds = NA_character_,
stringsAsFactors = FALSE))
})
f <- system.file("extdata", "guam.nc", package = "ncmeta")
nc <- RNetCDF::open.nc(f)
test_that("nc_coord_var brings back expected content for one variable", {
expect_equivalent(nc_coord_var(f, "RAINNC_present"),
data.frame(variable = "RAINNC_present", X = "XLONG", Y = "XLAT",
Z = NA_character_, T = "Time",
bounds = NA_character_, stringsAsFactors = FALSE))
expect_equal(nc_coord_var(f, "XLAT"),
NULL)
expect_equal(nc_coord_var(f, "Time")$T,
"Time")
})
test_that("nc_coord_vars brings back expected content for sample", {
coord_vars <- nc_coord_var(f)
expect_true(nrow(coord_vars) == 5)
coord_vars <- coord_vars[coord_vars$variable != "Time", ]
expect_true(nrow(coord_vars) == 4)
expect_true(all(coord_vars$X == "XLONG"))
expect_true(all(coord_vars$Y == "XLAT"))
expect_true(all(is.na(coord_vars$Z)))
expect_true(all(coord_vars$T == "Time"))
})
test_that("slightly broken projected coordinates work", {
f <- system.file("extdata", "daymet_sample.nc", package = "ncmeta")
expect_warning(coord_vars <- nc_coord_var(f),
"missing coordinate variables names in coordinates attribute trying to find non-auxiliary coordinate variables.")
expect_equal(as.character(coord_vars[coord_vars$variable == "prcp", ]),
c("prcp", "x", "y", NA, "time", NA))
expect_true(nrow(coord_vars) == 4)
expect_equal(as.character(coord_vars[coord_vars$variable == "time", ]),
c("time", NA, NA, NA, "time", "time_bnds"))
})
test_that("degen z", {
f <- system.file("extdata/avhrr-only-v2.19810901_header.nc", package = "ncmeta")
coord_vars <- nc_coord_var(f)
expect_true(all(is.na(coord_vars$Z)))
})
test_that("timeseries", {
f <- system.file("extdata/rasterwise-timeseries.nc", package = "ncmeta")
coord_vars <- nc_coord_var(f)
expect_equal(as.character(coord_vars[coord_vars$variable == "pr",]),
c("pr", "lon", "lat", NA, "time", NA))
expect_true(nrow(coord_vars) == 2)
})
test_that("high dim", {
f <- system.file("extdata/rasterwise-high-dim-test-1.nc", package = "ncmeta")
coord_vars <- nc_coord_var(f)
expect_true(nrow(coord_vars) == 0)
})
test_that("all the things", {
f <- system.file("extdata/rasterwise-bad_examples_62-example3.nc", package = "ncmeta")
coord_vars <- nc_coord_var(f)
expect_true(sum(coord_vars$variable == "pr") == 2)
})
ncmeta/tests/testthat/test-tidync.R 0000644 0001762 0000144 00000002274 14520356511 017124 0 ustar ligges users context("test-tidync.R")
context("filter")
# x1 <- tidync(f1) %>% activate("D5,D12") %>% hyper_filter(QCcheckNum = index < 2)
# x2 <- tidync(f1) %>% activate("D5,D12") %>% hyper_filter()
#
# nc_vars(f1)
# ## dimensions without variables
# x1 %>% expect_s3_class("tidync")
# x2 %>% expect_s3_class("tidync")
test_that("file open and metadata is ok", {
skip_on_cran()
f1 <- system.file("extdata/madishydro.nc", package = "ncmeta")
skip_if_not(file.exists(f1))
nc_axes(f1) %>% expect_s3_class("tbl_df") %>%
expect_named(c("axis", "variable", "dimension"))
})
#test_that("indexing works", {
# l3file <- system.file("extdata/oceandata",
# "S20080012008031.L3m_MO_CHL_chlor_a_9km.nc", package = "tidync")
# ind0 <- tidync(l3file) %>% hyper_filter()
# expect_that(ind0$dimension$count[ind0$dimension$active], equals(c(2160L, 4320L)))
# ind1 <- tidync(l3file) %>% hyper_filter(lon = index == 100)
# expect_that(ind1$dimension$count[ind0$dimension$active], equals(c(2160L, 1L)))
# expect_warning(ind2 <- tidync(l3file) %>% hyper_filter(lon = index %% 100 == 0))
# expect_that(ind2$dimension$count[ind2$dimension$active], equals(c(2160, 4201)))
#})
ncmeta/tests/testthat/test-file-bogeys.R 0000644 0001762 0000144 00000002067 14520356511 020037 0 ustar ligges users context("file-bogeys")
test_that("files and bad files are handled", {
skip_if_not(we_are_raady())
oisst_dayfile <- raadfiles::oisst_daily_files()$fullname[1]
nc_meta(oisst_dayfile) %>% expect_named(c("dimension", "variable", "attribute", "axis", "grid", "source"
))
oisst_monfile <- raadfiles::oisst_monthly_files()$fullname[1]
nc_meta(oisst_monfile) %>% expect_named(c("dimension", "variable", "attribute", "axis", "grid", "source"
))
roms_file <- raadtools::cpolarfiles()$fullname[1]
nc_meta(roms_file) %>% expect_named(c("dimension", "variable", "attribute", "axis", "grid", "source"
))
l3_file <- raadtools::ocfiles()$fullname[1]
expect_error(nc_vars(l3_file), "NetCDF: HDF error")
})
test_that("bad files and URLs fail gracefully", {
skip_on_travis() ## why does tis fail so badly on travis?
skip_on_cran()
expect_error(nc_meta(""), "empty string")
expect_error(nc_meta(), "must be a valid NetCDF source, filename or URL")
expect_error(nc_meta("https://abc")) ## let's not worry about the actual error: "NetCDF: I/O failure"
})
ncmeta/tests/testthat/test-file.R 0000644 0001762 0000144 00000002507 14520356511 016550 0 ustar ligges users context("file")
f <- system.file("extdata", "S2008001.L3m_DAY_CHL_chlor_a_9km.nc", package = "ncmeta")
#inq_structure <- structure(c("integer", "integer", "integer", "integer", "character"
#), .Names = c("ndims", "nvars", "ngatts", "unlimdimid", "filename"
#))
test_that("file inquiry works", {
inq <- nc_inq(f) %>% expect_s3_class("tbl_df")
expect_that(nrow(inq), equals(1L))
expect_that(inq$ndims, equals(4L))
expect_that(inq$nvars, equals(4L))
expect_that(inq$ngatts, equals( 65L))
expect_true(is.na(inq$unlimdimid))
# expect_that(unlist(lapply(inq, typeof)),
# equals(inq_structure))
})
test_that("multiple file inquiry works", {
inqfiles <- nc_inq(c(f, f)) %>% expect_s3_class("tbl_df")
expect_that(nrow(inqfiles), equals(2L))
expect_that(unique(inqfiles$ndims), equals(4L))
expect_that(unique(inqfiles$nvars), equals(4L))
expect_that(unique(inqfiles$ngatts), equals( 65L))
expect_true(is.na(unique(inqfiles$unlimdimid)))
# expect_that(unlist(lapply(inqfiles, typeof)),
# equals(inq_structure))
})
# test_that("thredds access works", {
# skip_on_cran()
# skip() ## ERDDAP hates us now
# u <- "https://upwell.pfeg.noaa.gov/erddap/tabledap/FRDCPSTrawlLHHaulCatch"
# thredds <- nc_inq(u) %>% expect_s3_class("tbl_df")
# expect_that(nrow(thredds), equals(1L))
#
# })
ncmeta/tests/testthat/test-utils.R 0000644 0001762 0000144 00000001447 14520356511 016773 0 ustar ligges users context("nc utils")
test_that("get_var_by_att", {
nc <- system.file("extdata/daymet_sample.nc", package = "ncmeta")
expect_true(ncmeta:::find_var_by_att(nc, "coordinates") == "prcp")
expect_true(length(ncmeta:::find_var_by_att(nc, "units")) == 4)
expect_true(length(ncmeta:::find_var_by_att(
nc, "long_name", "coordinate of projection", strict = FALSE)) == 2)
expect_true(length(ncmeta:::find_var_by_att(
nc, "long_name", "coordinate of projection", strict = TRUE)) == 0)
expect_true(length(ncmeta:::find_var_by_att(
nc, "units", "mm/day", strict = TRUE)) == 1)
nc <- RNetCDF::open.nc(nc)
expect_true(ncmeta:::find_var_by_att(nc, "coordinates") == "prcp")
expect_true(ncmeta:::find_var_by_att(ncmeta::nc_atts(nc),
"coordinates") == "prcp")
})
ncmeta/tests/testthat.R 0000644 0001762 0000144 00000000246 14520356511 014652 0 ustar ligges users sysname <- tolower(Sys.info()[["sysname"]])
if (!"sunos" %in% sysname) {
library(testthat)
library(ncmeta)
#skip_on_os("solaris")
test_check("ncmeta")
} ncmeta/R/ 0000755 0001762 0000144 00000000000 14520356511 011724 5 ustar ligges users ncmeta/R/tidync.R 0000644 0001762 0000144 00000000125 14520356511 013337 0 ustar ligges users #' @name nc_grids
#' @export
nc_grids.tidync <- function(x, ...) {
x[["grids"]]
} ncmeta/R/nc_variable.R 0000644 0001762 0000144 00000001573 14520356511 014322 0 ustar ligges users
#' NetCDF variables
#'
#' Generate a table of all variables.
#' @param x filename or handle
#' @param ... ignored currently
#'
#' @return data frame of variable information
#' @export
#'
nc_vars <- function(x, ...) {
UseMethod("nc_vars")
}
#' @name nc_vars
#' @export
nc_vars.character <- function(x, ...) {
if (nchar(x) < 1) stop("NetCDF source cannot be empty string")
nc <- RNetCDF::open.nc(x)
on.exit(RNetCDF::close.nc(nc), add = TRUE)
nc_vars(nc)
}
#' @name nc_vars
#' @export
#' @importFrom dplyr %>%
#' @importFrom rlang .data
nc_vars.NetCDF <- function(x, ...) {
nvars <- nc_inq(x)$nvars
if (nvars < 1) return(tibble::tibble())
nc_vars_internal(x, nvars)
}
nc_vars_internal <- function(x, nvars) {
dplyr::bind_rows(lapply(seq_len(nvars), function(i) nc_var(x, i-1))) %>%
dplyr::distinct(.data$id, .data$name, .data$type, .data$ndims, .data$natts)
} ncmeta/R/nc_att.R 0000644 0001762 0000144 00000010505 14520356511 013320 0 ustar ligges users #' NetCDF attributes
#'
#' Variable attributes are number 0:(n-1). Global attributes are indexed
#' by -1 or the label "NC_GLOBAL".
#'
#' `nc_inq` includes the number of global attributes
#' `nc_vars` includes the number of variable attributes
#' @param x or file handle
#' @param variable name or index (zero based) of variable
#' @param attribute name or index (zero based) of attribute
#' @param ... ignored
#'
#' @return data frame of attribute with numeric id, character attribute name,
#' character or numeric variable id or name depending on input, and attribute value.
#' @export
#'
#' @examples
#' f <- system.file("extdata", "S2008001.L3m_DAY_CHL_chlor_a_9km.nc", package = "ncmeta")
#' nc_att(f, 0, 0)
#' @name nc_att
#' @export
nc_att <- function(x, variable, attribute, ...) {
UseMethod("nc_att")
}
#' @name nc_att
#' @export
#' @importFrom rlang .data
#' @importFrom stats setNames
nc_att.NetCDF <- function(x, variable, attribute, ...) {
att_info <- RNetCDF::att.inq.nc(x, variable, attribute)
## att <- structure(RNetCDF::att.get.nc(x, variable, attribute), names = att_info$name)
att <- RNetCDF::att.get.nc(x, variable, attribute)
tibble::as_tibble(list(id = att_info$id, name = att_info$name, variable = variable,
value = setNames(list(att), att_info$name)))
}
#' @name nc_att
#' @export
#' @importFrom tibble tibble
nc_att.character <- function(x, variable, attribute, ...) {
if (nchar(x) < 1) stop("NetCDF source cannot be empty string")
nc <- RNetCDF::open.nc(x)
on.exit(RNetCDF::close.nc(nc), add = TRUE)
nc_att(nc, variable, attribute)
}
#' NetCDF attributes
#'
#' All attributes in the file, globals are treated as if they belong to variable 'NC_GLOBAL'. Attributes
#' for a single variable may be returned by specifying 'variable' - 'NC_GLOBAL' can stand in to return
#' only those attributes.
#' @param x filename or handle
#' @param variable optional single name of a variable, or 'NC_GLOBAL'
#' @param ... ignored
#'
#' @return data frame of attributes
#' @export
#'
#' @examples
#' f <- system.file("extdata", "S2008001.L3m_DAY_CHL_chlor_a_9km.nc", package = "ncmeta")
#' nc_atts(f)
nc_atts <- function(x, variable = NULL, ...) {
UseMethod("nc_atts")
}
#' @name nc_atts
#' @export
#' @importFrom dplyr distinct
#' @importFrom tibble tibble
nc_atts.NetCDF <- function(x, variable = NULL, ...) {
global <- tibble::as_tibble(list(id = -1, name = "NC_GLOBAL",
natts = nc_inq(x)$ngatts))
#vars <- nc_axes(x)
vars <- try(nc_vars(x), silent = TRUE)
## bomb out if ndims is NA
if (inherits(vars, "try-error") || nrow(vars) < 1L) {
warning("no variables recognizable")
atts <- lapply(seq_len(global$natts), function(a) nc_att(x, "NC_GLOBAL", a - 1))
if (length(atts) > 0) {
value <- unlist(lapply(atts, function(b) b$value), recursive = FALSE)
name <- unlist(lapply(atts, function(b) b$name))
} else {
value <- list()
name <- character(0)
}
global <- tibble::tibble(id = -1, name = name, variable = "NC_GLOBAL", value = value)
return(global)
} else {
#var <- dplyr::distinct(vars, .data$id, .data$name, .data$natts)
var <- vars[, c("id", "name", "natts")]
var <- var[!duplicated(var), ]
var <- dplyr::bind_rows(var, global)
if (!is.null(variable)) {
var <- dplyr::filter(var, .data$name == variable[1])
}
}
if (!is.null(variable) && !variable %in% var$name) stop("specified variable not found")
#bind_rows(lapply(split(var, var$name), function(v) bind_rows(lapply(seq_len(v$natts), function(iatt) nc_att(x, v$name, iatt - 1)))))
#bind_rows <- function(x) x
if (any(var$natts > 0)) {
out <- dplyr::bind_rows(lapply(split(var, var$name)[unique(var$name)],
function(v) dplyr::bind_rows(lapply(seq_len(v$natts), function(iatt) nc_att(x, v$name, iatt - 1)))))
} else {
out <- tibble::tibble(id = double(0), name = character(0), variable = character(0), value = list())
}
out
}
#varfun <- function(v) dplyr::bind_rows(lapply(seq_len(v$natts), function(iatt) nc_att(x, v$name, iatt - 1))))
#' @name nc_atts
#' @export
nc_atts.character <- function(x, variable = NULL, ...) {
if (nchar(x) < 1) stop("NetCDF source cannot be empty string")
nc <- RNetCDF::open.nc(x)
on.exit(RNetCDF::close.nc(nc), add = TRUE)
nc_atts(nc, variable = variable)
}
ncmeta/R/nc_axis.R 0000644 0001762 0000144 00000001264 14520356511 013476 0 ustar ligges users #' NetCDF axes
#'
#' An `axis` is an instance of a dimension.
#'
#' Each data source has a set of dimensions available for use by variables. Each axis is
#' a 1-dimensional instance.
#'
#' @param x NetCDF source
#' @param i index of axis (1-based, 0 is "empty")
#'
#' @name nc_axis
#' @export
nc_axis <- function(x, i) {
UseMethod("nc_axis")
}
#' @name nc_axis
#' @export
nc_axis.character <- function(x, i) {
if (nchar(x) < 1) stop("NetCDF source cannot be empty string")
nc <- RNetCDF::open.nc(x)
on.exit(RNetCDF::close.nc(nc), add = TRUE)
nc_axis(nc, i)
}
#' @name nc_axis
#' @export
nc_axis.NetCDF <- function(x, i) {
nc_axes(x) %>% dplyr::filter(.data$axis == i)
}
ncmeta/R/utils.R 0000644 0001762 0000144 00000004470 14520356511 013214 0 ustar ligges users ## https://gist.github.com/mdsumner/c086a5005c59373f4965fa6afd0d5a7c#gistcomment-2132051
# fast_tibble <- function(x) {
# stopifnot(length(unique(unlist(lapply(x, length)))) == 1L)
# structure(x, class = c("tbl_df", "tbl", "data.frame"), row.names = as.character(seq_along(x[[1]])))
# }
# use with caution! this will cause problems if a ragged list is given ...
faster_as_tibble <- function(x) {
## stopifnot(length(unique(lengths(x))) == 1L)
structure(x, class = c("tbl_df", "tbl", "data.frame"), row.names = as.integer(seq_along(x[[1]])))
}
split_fast_tibble <- function (x, f, drop = FALSE, ...)
lapply(split(x = seq_len(nrow(x)), f = f, ...),
function(ind) faster_as_tibble(lapply(x, "[", ind)))
we_are_raady <- function() {
fp <- getOption("default.datadir")
#print(fp)
stat <- FALSE
if (!is.null(fp) && file.exists(file.path(fp, "data"))) stat <- TRUE
stat
}
# This is a silly little function, but it can be useful.
#' Find NetCDF Variable by attribute
#' @description Given an attribute name and potentially a value,
#' searches for and returns variables with the desired attribute.
#'
#' @param x open NetCDF object, or character file path or url to be opened with
#' RNetCDF::open.nc
#' @param attribute character the attribute name to search for variables with
#' @param value character defaults to any only return variables that have the
#' attribute with the given value
#' @param strict boolean if TRUE, only exact matches of value will be returned
#'
#' @noRd
#'
#' @examples
#' nc <- system.file("extdata/metdata.nc", package = "intersectr")
#'
#' find_var_by_att(nc, "coordinates")
#'
#' find_var_by_att(nc, "units")
#'
#' find_var_by_att(nc, "units", "degrees", strict = FALSE)
#'
#' find_var_by_att(nc, "units", "degrees", strict = TRUE)
#'
#' find_var_by_att(nc, "units", "degrees_east", strict = TRUE)
#'
find_var_by_att <- function(x, attribute, value = ".*", strict = TRUE) {
open_nc <- FALSE
if (is.character(x)) {
x <- RNetCDF::open.nc(x)
open_nc <- TRUE
}
if (inherits(x, "NetCDF")) {
atts <- nc_atts(x)
} else if (inherits(x, "data.frame")) {
atts <- x
}
if (strict) value <- paste0("^", value, "$")
atts <- atts[atts$name == attribute, ]
atts <- atts[grepl(value, atts$value), ]
if (open_nc) RNetCDF::close.nc(x)
return(atts$variable)
}
ncmeta/R/nc_var.R 0000644 0001762 0000144 00000002211 14520356511 013313 0 ustar ligges users #' NetCDF variable
#'
#' Return a data frame about the variable at index `i`.
#' @param x file name or handle
#' @param i variable index (zero based)
#' @name nc_var
#' @return data frame of variable information
#' @seealso `nc_vars` to obtain information about all variables, `nc_inq` for an
#' overview of the file
#' @export
nc_var <- function(x, i) {
UseMethod("nc_var")
}
#'@name nc_var
#'@export
nc_var.character <- function(x, i) {
if (nchar(x) < 1) stop("NetCDF source cannot be empty string")
nc <- RNetCDF::open.nc(x)
on.exit(RNetCDF::close.nc(nc), add = TRUE)
nc_var(nc, i)
}
#'@name nc_var
#'@export
nc_var.NetCDF <- function(x, i) {
out <- RNetCDF::var.inq.nc(x, i)
# Convert dimids to empty vector when variable is scalar:
if (anyNA(out$dimids)) {
out$dimids <- integer(0)
}
# Store vector values as nested lists:
vectors <- c("dimids", "chunksizes", "filter_id", "filter_params")
listcols <- vectors[vectors %in% names(out)]
out[listcols] <- lapply(out[listcols], list)
# Keep only list items with length 1:
out <- out[lengths(out) == 1]
# Transform list to tibble row:
tibble::as_tibble_row(out)
}
ncmeta/R/nc_coord.R 0000644 0001762 0000144 00000016713 14520356511 013645 0 ustar ligges users #' Get Coordinate Variables for Given Variable
#'
#' In NetCDF, variables are defined along dimensions and are said to have "coordinate
#' variables" that define the (typically spatio-temporal) positions of the data's cells.
#'
#' This function attempts to identify the X, Y, Z, and T coordinate variables for each
#' data variable in the provided NetCDF source. The NetCDF-CF attribute conventions are
#' used to make this determination.
#'
#' All variables that can be related to a spatio-temporal axis, including coordinate
#' variables are returned. For coordinate variables, a "bounds" column is included in
#' the response indicating which variable contains bounds information.
#'
#' See \url{http://cfconventions.org/cf-conventions/v1.6.0/cf-conventions.html#coordinate-system}
#' for more.
#'
#' @return tibble with "variable", "X", "Y", "Z", "T", and "bounds" columns that reference
#' variables by name.
#'
#' @name nc_coord_var
#' @export
#' @examples
#' f <- system.file("extdata", "S2008001.L3m_DAY_CHL_chlor_a_9km.nc", package = "ncmeta")
#' nc_coord_var(f, "chlor_a")
#'
#' f <- system.file("extdata", "guam.nc", package = "ncmeta")
#' nc_coord_var(f)
nc_coord_var <- function(x, variable = NULL, ...) UseMethod("nc_coord_var")
#' @param x NetCDF source
#' @param variable variable name of interest.
#' If not included, all variables will be returned.
#' @param ... ignored
#'
#' @name nc_coord_var
#' @export
nc_coord_var.character <- function(x, variable = NULL, ...) {
if (nchar(x) < 1) stop("NetCDF source cannot be empty string")
nc <- RNetCDF::open.nc(x)
on.exit(RNetCDF::close.nc(nc), add = TRUE)
nc_coord_var_call(nc_dims(nc), nc_vars(nc), nc_atts(nc), nc_axes(x), variable)
}
#' @name nc_coord_var
#' @export
nc_coord_var.NetCDF <- function(x, variable = NULL, ...) {
nc_coord_var_call(nc_dims(x), nc_vars(x), nc_atts(x), nc_axes(x), variable)
}
#' @importFrom dplyr bind_rows
nc_coord_var_call <- function(dim, var, att, axe, variable) {
if (is.null(var) || (nrow(var) < 1 & nrow(dim) < 1)) return(tibble::tibble())
if(is.null(variable)) {
bind_rows(lapply(var$name,
function(v) nc_coord_var_finder(dim, var, att, axe, v)))
} else {
nc_coord_var_finder(dim, var, att, axe, variable)
}
}
#' @importFrom dplyr bind_rows filter select left_join group_by arrange mutate ungroup distinct
nc_coord_var_finder <- function(dim, var, att, axe, variable) {
if(nrow(att) == 0) return(NULL)
v_atts <- att$variable == variable
v_atts <- filter(att, v_atts)
aux = FALSE
if ("coordinates" %in% v_atts$name) {
# NetCDF-CF introduces a "coordinates" attribute
coordinates_atts <- filter(v_atts, name == "coordinates")
coord_vars <- strsplit(coordinates_atts[["value"]][[1]], " ")[[1]]
coord_vars <- coord_vars[nchar(coord_vars) > 0]
if(!any(coord_vars %in% var$name)) {
warning(paste("missing coordinate variables names in coordinates attribute",
"trying to find non-auxiliary coordinate variables."))
} else {
aux = TRUE
}
}
# COARDS style coordinate variables have the same name as a dimension.
v_dims <- axe$dimension[axe$variable == variable]
v_dims <- dim$name[dim$id %in% v_dims]
if(!aux) {
if(length(v_dims) == 0) return(NULL)
if(any(v_dims %in% var$name)) {
coord_vars <- v_dims[v_dims %in% var$name]
} else {
return(NULL)
}
} else {
if(any(v_dims %in% var$name)) {
coord_vars <- unique(c(coord_vars, v_dims[v_dims %in% var$name]))
}
}
coord_var <- sapply(coord_vars, divine_XYZT,
atts = filter(att, variable %in% coord_vars),
simplify = FALSE)
coord_var <- coord_var[!sapply(coord_var, is.null)]
if(length(coord_var) == 0) {
return(NULL)
} else {
coord_var_base <- tibble::as_tibble(list(coord_var = names(coord_var),
axis = unlist(coord_var)))
out <- tibble::tibble(variable = character(0),
X = character(0),
Y = character(0),
Z = character(0),
T = character(0))
# coordinate variables not named in a coordinates attribute relate
# by a shared dimension. First we need to get their dimension joined in.
coord_var <- coord_var_base %>%
left_join(select(axe, -axis), by = c("coord_var" = "variable"))
# Now we can build up a table that relates data variables to
# coordinate variables.
coord_var <- tibble::as_tibble(list(variable = variable)) %>%
left_join(select(axe, -axis), by = "variable") %>%
left_join(coord_var, by = "dimension") %>%
filter(!is.na(coord_var)) %>%
select(variable, axis, coord_var) %>%
distinct()
out <-tryCatch({
bind_rows(out, coord_var %>%
tidyr::spread(key = axis, value = coord_var))
}, error = function(e) {
# Takes care of the case where there are both normal and auxiliary coordinate variables.
bind_rows(out, filter(coord_var, !coord_var %in% dim$name) %>%
tidyr::spread(key = axis, value = coord_var),
filter(coord_var, coord_var %in% dim$name) %>%
tidyr::spread(key = axis, value = coord_var))
})
bounds <- get_bounds(att)
if(nrow(bounds) > 0) {
out <- left_join(out, bounds, by = "variable")
} else {
if(nrow(out) > 0) {
out$bounds <- NA_character_
} else {
out$bounds <- character(0)
}
}
return(out)
}
}
axis <- variable <- name <- value <- NULL
divine_XYZT <- function(var, atts) {
att_sub <- filter(atts, variable == var)
att_sub <- stats::setNames(att_sub$value, att_sub$name)
# By units is preferred by COARDS
lon_units <- c("degrees_east|degree_east|degree_E|degrees_E|degreeE|degreesE")
if(!is.null(att_sub[["units"]]) &&
grepl(lon_units, att_sub[["units"]], ignore.case = TRUE)) return("X")
lat_units <- "degrees_north|degree_north|degree_N|degrees_N|degreeN|degreesN"
if(!is.null(att_sub[["units"]]) &&
grepl(lat_units, att_sub[["units"]], ignore.case = TRUE)) return("Y")
# lat/lon by standard name
if(!is.null(att_sub[["standard_name"]]) &&
grepl("longitude", att_sub[["standard_name"]], ignore.case = TRUE)) return("X")
if(!is.null(att_sub[["standard_name"]]) &&
grepl("latitude", att_sub[["standard_name"]], ignore.case = TRUE)) return("Y")
if(!is.null(att_sub[["standard_name"]]) &&
grepl("time", att_sub[["standard_name"]], ignore.case = TRUE)) return("T")
# X/Y/Z/T by Axis
if(!is.null(att_sub[["axis"]])) return(att_sub[["axis"]])
if(!is.null(att_sub[["positive"]])) return("Z")
if(!is.null(att_sub[["units"]]) &&
grepl("since", att_sub[["units"]])) return("T")
if(any(grepl("x coordinate of projection", att_sub)) |
any(grepl("projection_x_coordinate", att_sub))) return("X")
if(any(grepl("y coordinate of projection", att_sub)) |
any(grepl("projection_y_coordinate", att_sub))) return("Y")
}
#' @importFrom rlang .data
get_bounds <- function(atts) {
dplyr::filter(atts, grepl("bounds", atts$name, ignore.case = TRUE)) %>%
dplyr::select(variable, bounds = value) %>%
dplyr::mutate(bounds = as.character(.data$bounds))
}
ncmeta/R/nc_grid.R 0000644 0001762 0000144 00000005576 14520356511 013471 0 ustar ligges users #' NetCDF grids
#'
#' A `grid` is a discretized space, defined by a set of dimensions. These are the spaces used
#' by one or more variables in a source. Traditional summaries are organized by variable, but
#' when organized by space or grid we can treat multiple variables together using standard
#' database techniques.
#'
#' Each data source has a set of dimensions available for use by variables. Each grid is
#' an n-dimensional space available for use by 0, 1 or more variables. A grid only really
#' exists if variable is defined for it, and 'grid' is an implicit entity not an explicit
#' part of the NetCDF API definition. The Unidata pages refer to "shape", which is more or less what
#' we mean by "grid".
#' @name nc_grids
#' @export
nc_grids <- function(x, ...) UseMethod("nc_grids")
#' @param x NetCDF source
#'
#' @param ... ignored
#'
#' @name nc_grids
#' @export
nc_grids.character <- function(x, ...) {
if (nchar(x) < 1) stop("NetCDF source cannot be empty string")
nc <- RNetCDF::open.nc(x)
on.exit(RNetCDF::close.nc(nc), add = TRUE)
nc_grids_dimvar(nc_dims(nc), nc_vars(nc), nc_axes(nc))
}
#' @name nc_grids
#' @export
#' @importFrom dplyr %>% arrange group_by
#' @importFrom tibble tibble
nc_grids.NetCDF <- function(x, ...) {
nc_grids_dimvar(nc_dims(x), nc_vars(x), nc_axes(x))
}
# nc_vars(f) ## should be distinct
# nc_axes(f) ## all of them
# nc_axes(f, var) ## just these ones
# nc_axis(i) ## just one, of all ??
expand_var <- function(x) {
nc_axes(x) %>%
dplyr::inner_join(nc_dims(x), c("dimension" = "id")) %>%
dplyr::inner_join(nc_vars(x), c("variable" = "name"))
}
#' @importFrom dplyr desc arrange
#' @importFrom rlang .data
nc_grids_dimvar <- function(dimension, variable, axes) {
if (is.null(variable) || (nrow(variable) < 1 & nrow(dimension) < 1)) return(tibble::tibble())
native_var <- unique(axes$variable)
shape_instances_byvar <- split(axes$dimension, axes$variable)[native_var]
shape_classify_byvar <- factor(unlist(lapply(shape_instances_byvar,
function(xb) paste(paste0("D", xb), collapse = ","))))
out <- tibble::as_tibble(list(variable = names(shape_classify_byvar),
grid = levels(shape_classify_byvar)[shape_classify_byvar]))
out <- dplyr::arrange(out, dplyr::desc(nchar(.data$grid)), .data$grid)
## catch the NA shapes (the scalars) and set to "-"
out[["grid"]][is.na(out[["grid"]]) | out[["grid"]] == "DNA"] <- "S"
out[["ndims"]] <- unlist(lapply(strsplit(out$grid, ","), length))
# out %>%
# dplyr::group_by(.data$grid, .data$ndims) %>%
# dplyr::summarize(nvars = dplyr::n()) %>%
# dplyr::ungroup()
if (utils::packageVersion("tidyr") > "0.8.3" ) {
nout <- tidyr::nest(out, variables = c(variable))
} else {
nout <- tidyr::nest(out, .data$variable, .key = "variables")
}
nout$nvars <- unlist(lapply(nout$variables, nrow))
nout
}
ncmeta/R/nc_dimension.R 0000644 0001762 0000144 00000001455 14520356511 014521 0 ustar ligges users #' NetCDF dimension
#'
#' Get information about the dimensions in a NetCDF source.
#' @param x file address or handle
#' @param ... ignored
#'
#' @name nc_dims
#' @export
nc_dims <- function(x, ...) {
UseMethod("nc_dims")
}
#' @name nc_dims
#' @export
nc_dims.character <- function(x, ...) {
if (nchar(x) < 1) stop("NetCDF source cannot be empty string")
nc <- RNetCDF::open.nc(x)
on.exit(RNetCDF::close.nc(nc), add = TRUE)
nc_dims(nc)
}
#' @name nc_dims
#' @export
nc_dims.NetCDF <- function(x, ...) {
dplyr::bind_rows(lapply(seq_len(nc_inq(x)$ndims), function(i) nc_dim(x, i-1)))
}
nc_dims_internal <- function(x, ndims, ...) {
dplyr::bind_rows(lapply(seq_len(ndims), function(i) nc_dim(x, i-1)))
}
#' @name nc_dims
#' @export
nc_dims.ncdf4 <- function(x, ...) {
nc_dims(x$filename)
}
ncmeta/R/nc_axes.R 0000644 0001762 0000144 00000003754 14520356511 013500 0 ustar ligges users #' NetCDF axes
#'
#' An `axis` is an instance of a dimension.
#'
#' Each data source has a set of dimensions available for use by variables. Each axis is
#' a 1-dimensional instance.
#'
#' @param x NetCDF source
#' @param variables names of vars to query
#' @param ... ignored
#'
#'@name nc_axes
#'@export
nc_axes <- function(x, variables = NULL, ...) {
UseMethod("nc_axes")
}
#'@name nc_axes
#'@export
nc_axes.character <- function(x, variables = NULL, ...) {
if (nchar(x) < 1) stop("NetCDF source cannot be empty string")
nc <- RNetCDF::open.nc(x)
on.exit(RNetCDF::close.nc(nc), add = TRUE)
nc_axes(nc, variables = variables, ...)
}
#'@name nc_axes
#'@export
#'@importFrom dplyr row_number transmute
#'@importFrom rlang .data
nc_axes.NetCDF <- function(x, variables = NULL, ...) {
if (is.null(variables)) {
vars_to_query <- nc_vars(x)
if (nrow(vars_to_query) < 1L) return(tibble())
variables <- vars_to_query$name
}
axes <- dplyr::bind_rows(
lapply(variables, function(variable) {
nc_axis_var(x, variable)
})
)
## if no dims, then it's not an axis see https://github.com/r-spatial/stars/pull/399
axes <- dplyr::filter(axes, .data$ndims > 0)
# axes$id <- seq_len(nrow(axes)) ## row_number wtf
#dplyr::transmute(axes, axis = row_number(), variable = .data$name, dimension = .data$dimids)
tibble::as_tibble(list(axis = seq_len(nrow(axes)), variable = axes[["name"]], dimension = axes[["dimids"]]))
}
## note this is a bit weird, but we have to ensure
## we work relative to all axes, so use the hidden function nc_axis_var
nc_axis_var <- function(x, i) {
out <- RNetCDF::var.inq.nc(x, i)[c("name", "ndims", "dimids")]
#dimids <- out$dimids
out[sapply(out, is.null)] <- NA
## as_tibble expands each vector to the length of the longest one
## which is what we want here
longest <- max(lengths(out))
if (longest > 1L) out <- lapply(out, function(a) rep_len(a, length.out = longest))
out <- out[lengths(out) > 0]
tibble::as_tibble(out)
}
ncmeta/R/ncmeta-package.r 0000644 0001762 0000144 00000003717 14520356641 014763 0 ustar ligges users #' @keywords internal
"_PACKAGE"
## usethis namespace: start
## usethis namespace: end
NULL
#' ncmeta: straightforward NetCDF metadata
#'
#' `ncmeta` provides a consistent set of tools to obtain metadata from NetCDF. NetCDF
#' is 'Network Common Data Form' https://www.unidata.ucar.edu/software/netcdf/.
#' These functions are generics, allowing methods to be written for various providers so that
#' everything can work from a common basis. All functions return a data frame.
#'
#' Each function responds to a character file name or data source (i.e. URL) or to a connection of a
#' given class, this is so a source connection may be created a minimal number of times and kept open
#' while a number of entities are queried.
#'
#' Each "given" entity may be referred to by index (0-based) or name, just as it would be by the NetCDF
#' API and by the two R wrapper providers `RNetCDF` and `ncdf4`.
#' \tabular{ll}{
#' \code{\link{nc_att}} \tab find the given attribute of a given variable \cr
#' \code{\link{nc_atts}} \tab find all attributes, of all variables and globals \cr
#' \code{\link{nc_axes}} \tab find all the instances of dimensions \cr
#' \code{\link{nc_axis}} \tab find given instance of a dimension (1-based) \cr
#' \code{\link{nc_dim}} \tab find the given dimension of a source (0-based) \cr
#' \code{\link{nc_dims}} \tab find all the dimensions of a source \cr
#' \code{\link{nc_grids}} \tab find the grids (sets of dimensions) of a source \cr
#' \code{\link{nc_inq}} \tab inquire about a source (i.e. number of dimensions, number of variables, number of global attributes and presence of unlimited dimension \cr
#' \code{\link{nc_meta}} \tab find all metadata for a source (runs all other functions) \cr
#' \code{\link{nc_sources}} \tab tags a record of a source and its "access time" \cr
#' \code{\link{nc_var}} \tab find a given variable (0-based) \cr
#' \code{\link{nc_vars}} \tab find the variables of a source \cr
#' }
#' @name ncmeta-package
NULL
ncmeta/R/nc_inq_file.R 0000644 0001762 0000144 00000002422 14520356511 014315 0 ustar ligges users # nc_meta <- function(x) {
# nc_vars(x)
# nc_dims(x)
#
# }
#' File info
#'
#' Get information about a NetCDF data source, may be a file path, or a `RNetCDF`
#' file handle, or an OpenDAP/Thredds server address.
#' @param x filename or handle
#' @param ... ignored
#'
#' @export
#' @examples
#' \donttest{
#' \dontrun{
#' f <- raadfiles:::cmip5_files()$fullname[1]
#' nc_inq(f)
#' nc_var(f, 0)
#' nc_dim(f, 0)
#' }
#' }
#' f <- system.file("extdata", "S2008001.L3m_DAY_CHL_chlor_a_9km.nc", package = "ncmeta")
#' nc_inq(f)
#' nc_var(f, 0)
#' nc_dim(f, 0)
#'
#' nc_vars(f)
#' nc_dims(f)
nc_inq <- function(x, ...) {
UseMethod("nc_inq")
}
#' @name nc_inq
#' @export
#' @importFrom RNetCDF file.inq.nc
#' @importFrom tibble as_tibble
nc_inq.NetCDF <- function(x, ...) {
tibble::as_tibble(RNetCDF::file.inq.nc(x))
}
#' @name nc_inq
#' @export
#' @importFrom dplyr bind_rows
nc_inq.character <- function(x, ...) {
ifun <- function(x) {
if (nchar(x) < 1) stop("NetCDF source cannot be empty string")
nc <- RNetCDF::open.nc(x)
on.exit(RNetCDF::close.nc(nc), add = TRUE)
nc_inq(nc)
}
out <- dplyr::bind_rows( lapply(x, ifun), .id = "filename")
out$filename <- x[as.integer(out$filename)]
out[, c("ndims", "nvars", "ngatts", "unlimdimid", "filename")]
}
ncmeta/R/nc_dim.R 0000644 0001762 0000144 00000001444 14520356511 013303 0 ustar ligges users #' NetCDF variables
#' Obtain information about a single dimension by index.
#' @param x filename or handle
#' @param ... ignored
#' @param i index of dimension (zero based)
#'
#' @name nc_dim
#' @seealso `nc_vars` to obtain information about all dimensions, `nc_inq` for an
#' overview of the file
#' @export
nc_dim <- function(x, i, ...) {
UseMethod("nc_dim")
}
#'@name nc_dim
#'@export
nc_dim.character <- function(x, i, ...) {
if (nchar(x) < 1) stop("NetCDF source cannot be empty string")
nc <- RNetCDF::open.nc(x)
on.exit(RNetCDF::close.nc(nc), add = TRUE)
nc_dim(nc, i)
}
#'@name nc_dim
#'@export
nc_dim.NetCDF <- function(x, i, ...) {
tibble::as_tibble(RNetCDF::dim.inq.nc(x, i))
}
#'@name nc_dim
#'@export
nc_dim.ncdf4 <- function(x, i, ...) {
nc_dim(x$filename, i, ...)
}
ncmeta/R/nc-gridmapping.R 0000644 0001762 0000144 00000030063 14520356511 014750 0 ustar ligges users #' Get Grid Mapping
#'
#' @description Get the grid mapping from a NetCDF file
#'
#' @return tibble containing attributes that make up the file's grid_mapping.
#' A data_variable column is included to indicate which data variable the grid
#' mapping belongs to.
#' @export
#'
#' @name nc_grid_mapping_atts
#' @examples
#'
#' nc_grid_mapping_atts(system.file("extdata/daymet_sample.nc", package = "ncmeta"))
nc_grid_mapping_atts <- function(x, data_variable = NULL) UseMethod("nc_grid_mapping_atts")
#' @param x open NetCDF object, character file path or url to be
#' opened with RNetCDF::open.nc, or data.frame as returned from ncmeta::nc_atts
#'
#' @param data_variable character variable of interest
#'
#' @name nc_grid_mapping_atts
#' @export
nc_grid_mapping_atts.character <- function(x, data_variable = NULL) {
nc <- RNetCDF::open.nc(x)
on.exit(RNetCDF::close.nc(nc), add = TRUE)
nc_grid_mapping_atts(nc, data_variable)
}
#' @name nc_grid_mapping_atts
#' @export
nc_grid_mapping_atts.NetCDF <- function(x, data_variable = NULL) {
nc_grid_mapping_atts(nc_atts(x), data_variable)
}
#' @name nc_grid_mapping_atts
#' @export
nc_grid_mapping_atts.data.frame <- function(x, data_variable = NULL) {
gm_att <- "grid_mapping"
if(is.null(data_variable)) {
data_variable <- find_var_by_att(x, gm_att)
} else if(!gm_att %in% dplyr::filter(x, variable == data_variable)$name) {
warning(paste("no grid_mapping attribute found for this variable"))
return(tibble::tibble())
}
if (length(data_variable) == 0 ) {
warning(paste("No variables with a grid mapping found.\n",
"Defaulting to WGS84 Lon/Lat"))
return(tibble::as_tibble(list(name = c("grid_mapping_name",
"semi_major_axis",
"inverse_flattening",
"longitude_of_prime_meridian"),
value = list("latitude_longitude",
6378137,
298.257223563,
0))))
}
grid_mapping_vars <- dplyr::filter(x, variable %in% data_variable &
name %in% gm_att) %>%
dplyr::mutate(value = as.character(value))
grid_mapping_atts <- dplyr::filter(x, variable %in% grid_mapping_vars$value)
grid_mapping_atts <-
dplyr::left_join(grid_mapping_atts,
select(grid_mapping_vars, data_variable = variable, value = value),
by = c("variable" = "value"))
return(grid_mapping_atts)
}
#' Get NetCDF-CF grid mapping from projection
#'
#' Takes a proj4 string and returns a NetCDF-CF projection as
#' a named list of attributes.
#'
#' @param prj character PROJ string as used in raster, sf, sp, proj4, and rgdal packages.
#'
#' @return A named list containing attributes required for that grid_mapping.
#'
#'
#' @references
#' \enumerate{
#' \item \url{https://en.wikibooks.org/wiki/PROJ.4}
#' \item \url{https://trac.osgeo.org/gdal/wiki/NetCDF_ProjectionTestingStatus}
#' \item \url{http://cfconventions.org/cf-conventions/cf-conventions.html#appendix-grid-mappings}
#' }
#'
#' @export
#'
#' @examples
#' prj <- "+proj=longlat +datum=NAD27 +no_defs"
#' nc_prj_to_gridmapping(prj)
#' p1 <- "+proj=aea +lat_1=29.5 +lat_2=45.5 +lat_0=23 +lon_0=-96"
#' p2 <- "+x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs"
#' prj2 <- sprintf("%s %s", p1, p2)
#' nc_prj_to_gridmapping(prj2)
#'
#' nc_prj_to_gridmapping("+proj=longlat +a=6378137 +f=0.00335281066474748 +pm=0 +no_defs")
#'
nc_prj_to_gridmapping <- function(prj) {
al <- prepCRS(prj)
if(is.null(al)) {
return(tibble::as_tibble(list(name = character(0), value = list())))
} else {
gm <- GGFP(al)
return(tibble::as_tibble(list(name = names(gm), value = unname(gm))))
}
}
GGFP <- function(al) UseMethod("GGFP")
GGFP.latitude_longitude <- function(al) {
gm <- c(list(grid_mapping_name = "latitude_longitude"),
getGeoDatum_gm(al))
gm
}
GGFP.albers_conical_equal_area <- function(al) {
gm <- c(list(grid_mapping_name = "albers_conical_equal_area"),
lonCentMer_gm(al),
latProjOrig_gm(al),
falseEastNorth_gm(al),
standPar_gm(al),
getGeoDatum_gm(al))
gm
}
GGFP.azimuthal_equidistant <- function(al) {
gm <- c(list(grid_mapping_name = "azimuthal_equidistant"),
lonProjOrig_gm(al),
latProjOrig_gm(al),
falseEastNorth_gm(al),
getGeoDatum_gm(al))
gm
}
GGFP.lambert_azimuthal_equal_area <- function(al) {
gm <- c(list(grid_mapping_name = "lambert_azimuthal_equal_area"),
latProjOrig_gm(al),
lonProjOrig_gm(al),
falseEastNorth_gm(al),
getGeoDatum_gm(al))
gm
}
GGFP.lambert_conformal_conic <- function(al) {
gm <- c(list(grid_mapping_name = "lambert_conformal_conic"),
standPar_gm(al),
falseEastNorth_gm(al),
latProjOrig_gm(al),
lonCentMer_gm(al),
getGeoDatum_gm(al))
gm
}
GGFP.lambert_cylindrical_equal_area <- function(al) {
gm <- c(list(grid_mapping_name = "lambert_cylindrical_equal_area"),
lonCentMer_gm(al),
oneStandPar_gm(al),
falseEastNorth_gm(al),
getGeoDatum_gm(al))
gm
}
GGFP.mercator <- function(al) {
if(!is.null(al$k)) {
gm <- c(list(grid_mapping_name = "mercator"),
lonProjOrig_gm(al),
scaleFactorProjOrig_gm(al),
falseEastNorth_gm(al),
getGeoDatum_gm(al))
} else {
gm <- c(list(grid_mapping_name = "mercator"),
lonProjOrig_gm(al),
oneStandPar_gm(al),
falseEastNorth_gm(al),
getGeoDatum_gm(al))
}
gm
}
GGFP.oblique_mercator <- function(al) {
#!!!! Check this one out. the oMerc function is a hack !!!!
gm <- c(list(grid_mapping_name = "oblique_mercator"),
latProjOrig_gm(al),
lonProjCent_gm(al),
scaleFactorProjOrig_gm(al),
oMerc_gm(al),
falseEastNorth_gm(al),
getGeoDatum_gm(al))
gm
}
GGFP.orthographic <- function(al) {
gm <- c(list(grid_mapping_name = "orthographic"),
latProjOrig_gm(al),
lonProjOrig_gm(al),
falseEastNorth_gm(al),
getGeoDatum_gm(al))
gm
}
# GGFP.polar_stereographic <- function(al) {
# if(!is.null(al$k)) {
# gm <- c(list(grid_mapping_name = "polar_stereographic"),
# latProjOrig_gm(al),
# stVertLon_gm(al),
# scaleFactorProjOrig_gm(al),
# falseEastNorth_gm(al),
# getGeoDatum_gm(al))
# } else {
# gm <- c(list(grid_mapping_name = "polar_stereographic"),
# latProjOrig_gm(al),
# stVertLon_gm(al),
# oneStandPar_gm(al),
# falseEastNorth_gm(al),
# getGeoDatum_gm(al))
# }
# gm
# }
# GGFP.sinusoidal <- function(al) {
# gm <- c(list(grid_mapping_name = "sinusoidal"),
# lonProjOrig_gm(al),
# falseEastNorth_gm(al),
# getGeoDatum_gm(al))
# gm
# }
GGFP.stereographic <- function(al) {
gm <- c(list(grid_mapping_name = "stereographic"),
latProjOrig_gm(al),
lonProjOrig_gm(al),
scaleFactorProjOrig_gm(al),
falseEastNorth_gm(al),
getGeoDatum_gm(al))
gm
}
GGFP.transverse_mercator <- function(al) {
gm <- c(list(grid_mapping_name = "transverse_mercator"),
latProjOrig_gm(al),
lonCentMer_gm(al),
scaleFactorCentMer_gm(al),
falseEastNorth_gm(al),
getGeoDatum_gm(al))
gm
}
lonCentMer_gm <- function(al) {
list(longitude_of_central_meridian = as.numeric(al$lon_0))
}
latProjOrig_gm <- function(al) {
list(latitude_of_projection_origin = as.numeric(al$lat_0))
}
lonProjOrig_gm <- function(al) {
list(longitude_of_projection_origin = as.numeric(al$lon_0))
}
falseEastNorth_gm <- function(al) {
list(false_easting = as.numeric(al$x_0),
false_northing = as.numeric(al$y_0))
}
standPar_gm <- function(al) {
if(al$lat_1 != al$lat_2) {
list(standard_parallel = c(as.numeric(al$lat_1), as.numeric(al$lat_2)))
} else if(al$lat_1 == al$lat_2) {
list(standard_parallel = as.numeric(al$lat_1))
}
}
oneStandPar_gm <- function(al) {
list(standard_parallel = c(as.numeric(al$lat_ts)))
}
getGeoDatum_gm <- function(al) {
if(!is.null(al$datum) && al$datum == "NAD83") {
list(semi_major_axis = 6378137,
inverse_flattening = 298.257222101,
longitude_of_prime_meridian = 0)
} else if(!is.null(al$datum) && al$datum == "WGS84") {
list(semi_major_axis = 6378137,
inverse_flattening = 298.257223563,
longitude_of_prime_meridian = 0)
} else if(!is.null(al$datum) && al$datum == "NAD27") {
list(semi_major_axis = 6378206.4,
inverse_flattening = 294.978698214,
longitude_of_prime_meridian = 0)
} else if(!is.null(al$ellps) &&
!is.null(al$towgs84) &&
al$towgs84 == "0,0,0,0,0,0,0") {
list(semi_major_axis = 6378137,
inverse_flattening = 298.257223563,
longitude_of_prime_meridian = 0)
} else if(!is.null(al$a) && !is.null(al$f) && !is.null(al$pm)) {
list(semi_major_axis = as.numeric(al$a),
inverse_flattening = (1/as.numeric(al$f)),
longitude_of_prime_meridian = as.numeric(al$pm))
} else if(!is.null(al$a) && !is.null(al$b) && !is.null(al$pm)) {
list(semi_major_axis = as.numeric(al$a),
semi_minor_axis = as.numeric(al$b),
longitude_of_prime_meridian = as.numeric(al$pm))
} else {
warning("no datum information found assuming WGS84")
list(semi_major_axis = 6378137,
inverse_flattening = 298.257223563,
longitude_of_prime_meridian = 0)
}
}
scaleFactorCentMer_gm <- function(al) {
list(scale_factor_at_central_meridian = as.numeric(al$k))
}
scaleFactorProjOrig_gm <- function(al) {
list(scale_factor_at_projection_origin = as.numeric(al$k))
}
oMerc_gm <- function(al) {
list(azimuth_of_central_line = as.numeric(al$alpha))
}
lonProjCent_gm <- function(al) {
list(longitude_of_projection_origin = as.numeric(al$lonc))
}
check_args <- function (x)
{
## FIXME: checks as in reproj stop("cannot convert from digits, did you enter an EPSG code?")
if (is.numeric(x) || (nchar(x) %in% c(4, 5) && grepl("^[0-9]{1,5}$",
x))) {
return(FALSE)
}
if (!substr(x, 1, 1) == "+")
return(FALSE)
TRUE
}
prepCRS <- function(prj) {
if(inherits(prj, "CRS")) prj <- prj@projargs
if(!check_args(prj)[1][[1]]) {
warning("not a valid crs, returning an empty tibble")
return(NULL)
}
args <- unique(unlist(strsplit(prj, " ")))
argList <- list()
for(arg in args) {
a <- unlist(strsplit(sub("\\+", "", arg), "="))
argList[a[1]] <- a[2]
}
cf_proj_lookup <- list(aea = "albers_conical_equal_area",
aeqd = "azimuthal_equidistant",
laea = "lambert_azimuthal_equal_area",
lcc = "lambert_conformal_conic",
cea = "lambert_cylindrical_equal_area",
longlat = "latitude_longitude",
merc = "mercator",
omerc = "oblique_mercator",
ortho = "orthographic",
stere = "stereographic",
tmerc = "transverse_mercator")
class(argList) <- cf_proj_lookup[unlist(argList["proj"])][[1]]
if(!class(argList) %in% cf_proj_lookup) {
warning("no available mapping to netcdf projection, returning empty crs list")
return(NULL) } else {
return(argList) }
}
ncmeta/R/nc-prj.R 0000644 0001762 0000144 00000021121 14520356511 013235 0 ustar ligges users #' Get projection from NetCDF-CF Grid Mapping
#'
#' Takes NetCDF-CF grid mapping attributes and returns
#' a proj4 string.
#'
#' The WGS84 datum is used as a default if one os not provided
#' in the grid mapping.
#'
#' If only a semi_major axis is provided, a sperical earth is assumed.
#'
#' @param x list or data.frame of attributes of the grid mapping variable
#' as returned by ncdf or ncdf4's get attributes functions or ncmeta's nc_grid_mapping_atts.
#'
#' @return A proj4 string.
#'
#' @references
#' \enumerate{
#' \item \url{https://en.wikibooks.org/wiki/PROJ.4}
#' \item \url{https://trac.osgeo.org/gdal/wiki/NetCDF_ProjectionTestingStatus}
#' \item \url{http://cfconventions.org/cf-conventions/cf-conventions.html#appendix-grid-mappings}
#' }
#'
#' @export
#' @examples
#'
#' crs <- list(grid_mapping_name="latitude_longitude",
#' longitude_of_prime_meridian = 0,
#' semi_major_axis = 6378137,
#' inverse_flattening = 298)
#' nc_gm_to_prj(crs)
nc_gm_to_prj <- function(x) UseMethod("nc_gm_to_prj")
#' @name nc_gm_to_prj
#' @export
nc_gm_to_prj.data.frame <- function(x) {
nc_gm_to_prj(stats::setNames(x$value, x$name))
}
#' @name nc_gm_to_prj
#' @export
nc_gm_to_prj.list <- function(x) {
class(x) <- x$grid_mapping_name
GPFN(x)
}
GPFN <- function(gm) UseMethod("GPFN")
GPFN.albers_conical_equal_area <- function(gm) {
projargs <- paste("+proj=aea",
standPar(gm),
falseEastNorth(gm),
latProjOrig(gm),
lonCentMer(gm),
getGeoDatum(gm))
}
GPFN.azimuthal_equidistant <- function(gm) {
projargs <- paste("+proj=aeqd",
latProjOrig(gm),
lonProjOrig(gm),
falseEastNorth(gm),
getGeoDatum(gm))
}
# GPFN.geostationary <- function(gm) {
# #+proj=geos +lon_0=0 +h=-0 +x_0=0 +y_0=0 +no_defs
# projargs <- paste("+proj=geos",
# latProjOrig(gm),
# lonProjOrig(gm),
# # persHeight(gm),
# falseEastNorth(gm),
# getGeoDatum(gm))
# # Fixed angle and sweep angle axes?
# }
GPFN.lambert_azimuthal_equal_area <- function(gm) {
projargs <- paste("+proj=laea",
latProjOrig(gm),
lonProjOrig(gm),
falseEastNorth(gm),
getGeoDatum(gm))
}
GPFN.lambert_conformal_conic <- function(gm) {
projargs <- paste("+proj=lcc",
standPar(gm),
falseEastNorth(gm),
latProjOrig(gm),
lonCentMer(gm),
getGeoDatum(gm))
}
GPFN.lambert_cylindrical_equal_area <- function(gm) {
projargs <- paste("+proj=cea",
lonCentMer(gm),
oneStandPar(gm),
falseEastNorth(gm),
getGeoDatum(gm))
}
GPFN.latitude_longitude <- function(gm) {
prj <- paste0("+proj=longlat ", getGeoDatum(gm))
}
GPFN.mercator <- function(gm) {
if(!is.null(gm$scale_factor_at_projection_origin)) {
projargs <- paste("+proj=merc",
lonProjOrig(gm),
scaleFactorProjOrig(gm),
falseEastNorth(gm),
getGeoDatum(gm))
} else {
projargs <- paste("+proj=merc",
lonProjOrig(gm),
oneStandPar(gm),
falseEastNorth(gm),
getGeoDatum(gm))
}
}
GPFN.oblique_mercator <- function(gm) {
#!!!! Check this one out. the oMerc function is a hack !!!!
projargs <- paste("+proj=omerc",
latProjOrig(gm),
lonProjCent(gm),
scaleFactorProjOrig(gm),
oMerc(gm),
falseEastNorth(gm),
getGeoDatum(gm))
}
GPFN.orthographic <- function(gm) {
projargs <- paste("+proj=ortho",
latProjOrig(gm),
lonProjOrig(gm),
falseEastNorth(gm),
getGeoDatum(gm))
}
GPFN.polar_stereographic <- function(gm) {
if(!is.null(gm$scale_factor_at_projection_origin)) {
projargs <- paste("+proj=stere",
latProjOrig(gm),
stVertLon(gm),
scaleFactorProjOrig(gm),
falseEastNorth(gm),
getGeoDatum(gm))
} else {
projargs <- paste("+proj=stere",
latProjOrig(gm),
stVertLon(gm),
oneStandPar(gm),
falseEastNorth(gm),
getGeoDatum(gm))
}
}
# GPFN.rotated_latitude_longitude <- function(gm) {
# # not supported?
# }
#
GPFN.sinusoidal <- function(gm) {
projargs <- paste("+proj=sinu",
lonProjOrig(gm),
falseEastNorth(gm),
getGeoDatum(gm))
}
#
GPFN.stereographic <- function(gm) {
projargs <- paste("+proj=stere",
latProjOrig(gm),
lonProjOrig(gm),
scaleFactorProjOrig(gm),
falseEastNorth(gm),
getGeoDatum(gm))
}
GPFN.transverse_mercator <- function(gm) {
projargs <- paste("+proj=tmerc",
latProjOrig(gm),
lonCentMer(gm),
scaleFactorCentMer(gm),
falseEastNorth(gm),
getGeoDatum(gm))
}
#
# GPFN.vertical_perspective <- function(gm) {
# #"+proj=nsper +h=1"
# Not supported?
# }
getGeoDatum <- function(gm) {
if(is.null(gm$longitude_of_prime_meridian)) {
warning("Didn't find a longitude of prime meridian for datum, assuming 0.")
gm$longitude_of_prime_meridian <- 0
}
if(is.null(gm$semi_major_axis)) {
if(!is.null(gm$earth_radius)) {
warning("Didn't find a semi major axis but did find earth radius. Assuming spherical earth")
gm$semi_major_axis <- gm$earth_radius
gm$semi_minor_axis <- gm$earth_radius
} else {
warning("Didn't find a semi major axis for datum, assuming WGS84 6378137.0 meters")
gm$semi_major_axis <- 6378137.0
if(is.null(gm$inverse_flattening) && is.null(gm$semi_minor_axis)) {
warning("Didn't find an inverse flattening value, assuming WGS84 298.257223563")
gm$inverse_flattening <- 298.257223563
}
}
}
if(!is.null(gm$inverse_flattening) && gm$inverse_flattening == 0) {
gm$inverse_flattening <- NULL
gm$semi_minor_axis <- gm$semi_major_axis
}
if(!is.null(gm$inverse_flattening)) {
geoDatum <- paste0("+a=", gm$semi_major_axis,
" +f=", (1/gm$inverse_flattening),
" +pm=", gm$longitude_of_prime_meridian,
" +no_defs")
} else if(!is.null(gm$semi_minor_axis)) {
geoDatum <- paste0("+a=", gm$semi_major_axis,
" +b=", gm$semi_minor_axis,
" +pm=", gm$longitude_of_prime_meridian,
" +no_defs")
} else {
geoDatum <- paste0("+a=", gm$semi_major_axis,
" +b=", gm$semi_major_axis,
" +pm=", gm$longitude_of_prime_meridian,
" +no_defs")
}
return(geoDatum)
}
standPar <- function(gm) {
if(length(gm$standard_parallel)==1) {
gm$standard_parallel <-
c(gm$standard_parallel,
gm$standard_parallel)
}
outString <- paste0("+lat_1=", gm$standard_parallel[1],
" +lat_2=", gm$standard_parallel[2])
}
oneStandPar <- function(gm) {
outString <- paste0("+lat_ts=", gm$standard_parallel[1])
}
falseEastNorth <- function(gm) {
options(scipen=2)
outString <- paste0("+x_0=", gm$false_easting,
" +y_0=", gm$false_northing,
" +units=m")
}
latProjOrig <- function(gm) {
outString <- paste0("+lat_0=", gm$latitude_of_projection_origin)
}
lonCentMer <- function(gm) {
outString <- paste0("+lon_0=", gm$longitude_of_central_meridian)
}
lonProjOrig <- function(gm) {
outString <- paste0("+lon_0=", gm$longitude_of_projection_origin)
}
stVertLon <- function(gm) {
outString <- paste0("+lon_0=", gm$straight_vertical_longitude_from_pole)
}
scaleFactorCentMer <- function(gm) {
outString <- paste0("+k=", gm$scale_factor_at_central_meridian)
}
scaleFactorProjOrig <- function(gm) {
outString <- paste0("+k=", gm$scale_factor_at_projection_origin)
}
oMerc <- function(gm) {
outString <- paste0("+alpha=", gm$azimuth_of_central_line,
" +gamma=", gm$azimuth_of_central_line,
" +no_uoff")
}
lonProjCent <- function(gm) {
outString <- paste0("+lonc=", gm$longitude_of_projection_origin)
}
ncmeta/R/nc_meta.R 0000644 0001762 0000144 00000003627 14520356511 013465 0 ustar ligges users #' Top level NetCDF metadata.
#'
#' This function exists to maintain the open connection
#' while all dimension, variable, and attribute metadata is extracted.
#'
#' This function is pretty ambitious, and will send nearly any string
#' to the underlying NetCDF library other than "", which immediately
#' generates an error. This should be robust, but might present fairly
#' obscure error messages from the underlying library.
#' @param ... ignored
#' @param x data source address, file name or handle
#'
#' @export
#' @examples
#' f <- system.file("extdata", "S2008001.L3m_DAY_CHL_chlor_a_9km.nc", package = "ncmeta")
#' nc_meta(f)
#' \donttest{
#' \dontrun{
#' u <- "https://upwell.pfeg.noaa.gov/erddap/tabledap/FRDCPSTrawlLHHaulCatch"
#' nc_meta(u)
#' }}
nc_meta <- function(x, ...) {
if (missing(x)) stop("'x' must be a valid NetCDF source, filename or URL")
UseMethod("nc_meta")
}
#' @name nc_meta
#' @export
nc_meta.NetCDF <- function(x, ...) {
inq <- nc_inq(x)
dims <- nc_dims_internal(x, inq[["ndims"]])
vars <- nc_vars_internal(x, inq$nvars)
if (nrow(vars) > 1) axis <- nc_axes(x, vars$name) else axis <- nc_axes(x)
## does a dimension have dim-vals?
if (nrow(dims) > 0) dims[["coord_dim"]] <- dims[["name"]] %in% vars[["name"]]
## is a variable a dim-val?
if (nrow(vars) > 0) {
vars[["dim_coord"]] <- vars[["ndims"]] == 1L & vars[["name"]] %in% dims[["name"]]
} else {
vars <- NULL ## avoid passing along a 0-row data frame
}
structure(list(dimension = dims,
variable = vars,
attribute = nc_atts(x),
axis = axis,
grid = nc_grids_dimvar(dims, vars, axis)),
class = "ncmeta")
}
#' @name nc_meta
#' @export
nc_meta.character <- function(x, ...) {
if (nchar(x) < 1) stop("NetCDF source cannot be empty string")
nc <- RNetCDF::open.nc(x)
on.exit(RNetCDF::close.nc(nc), add = TRUE)
out <- nc_meta(nc)
out$source <- nc_sources(x)
out
} ncmeta/R/nc_sources.R 0000644 0001762 0000144 00000000731 14520356511 014213 0 ustar ligges users #' NetCDF sources
#'
#' A record of file, URL, or any data source with NetCDF.
#' @param x data source string
#'
#' @param ... ignored
#'
#' @name nc_sources
#' @export
nc_sources <- function(x, ...) {
UseMethod("nc_sources")
}
#' @name nc_sources
#' @export
nc_sources.character <- function(x, ...) {
if (file.exists(x)) {
path <- normalizePath(x, winslash = "/")
} else {
path <- x
}
tibble(access = Sys.time(), source = path)
}
ncmeta/NEWS.md 0000644 0001762 0000144 00000004745 14520356702 012635 0 ustar ligges users # ncmeta 0.3.6
* Fixed namespace doc thanks to CRAN.
# ncmeta 0.3.5
* Removed LazyData, unused.
* Extra info now provided by RNetCDF was causing non-nested data frame problems,
fixed by PR from @mjwoods in #44 and #45.
* Changed default branch name to "main", so please check if you have a fork and submit PRs.
* Fix bug where Scalar variables were treated as an axis. Picked up in stars PR #399.
# ncmeta 0.3.0
* Fix file path mangling introduced in #27.
# ncmeta 0.2.5
* Improved equivalence test thanks to Romain Francois #37.
# ncmeta 0.2.0
* Simplified error handling when file not able to be opened. https://github.com/ropensci/tidync/issues/98
* Fixed bug in nc_atts() https://github.com/hypertidy/ncmeta/issues/36.
# ncmeta 0.1.0
* Extra checks and fixes to align with stars, and a future release of RNetCDF.
* Condition on version of tidyr for new `nest()` syntax > 0.8.3.
* The output of `nc_atts()` is now more consistent, with the same structure given for
only global attributes, or a mix of variable attributes and global attributes. If
there are no attributes at all the output has zero rows, but now has the correct
column types.
# ncmeta 0.0.4
* `nc_grids()` now normal form, with nested variables so we can easily link grids to variables.
* New functions `nc_coord_var` to find coordinate variables (if any),
`gm_to_prj` to determine PROJ string in use, and `nc_grid_mapping_atts` to
determine grid mapping parameters; #19, #14, #12, #9.
# ncmeta 0.0.3
* Fix for grid organization providing variables out of native order.
* Added 'variable' argument to 'nc_atts', per #8.
# ncmeta 0.0.2
* added some extra checks for bad source strings, particularly the empty string
to prevent crashing (this happens with `system.file()` where the file does not
exist)
* fix attribute types problem
# ncmeta 0.0.1
*updates from CRAN feedback
* ncmeta now provides support for dimensions that do not have explicit
coordinates: dimension and variable tables now have information about
"dimvals", in the form of "dim_coord" and "coord_dim" i.e. if a variable
is 1D and its name corresponds to a dimension name, then it is a rectlinear
coordinate vector of that dimension. (The coordinates can be of type "char",
and that must be dealt with down stream as it now is in tidync).
* new function nc_grids, the spaces available to variables
* new function nc_axes, nc_axis for the instances of dimensions
* nc_vars now returns only variables
* First working version.
ncmeta/MD5 0000644 0001762 0000144 00000007321 14520367022 012035 0 ustar ligges users b8b386d4569d8c80b1b3c350259bce85 *DESCRIPTION
8d42254a59eb87976829d74ed97da073 *NAMESPACE
41ec92c84af07f44e857e69568508bfc *NEWS.md
7202096630392c669cca71f5585518e2 *R/nc-gridmapping.R
95808ce7524160eb0e7a0c59c3b489c0 *R/nc-prj.R
8b1f76a3f6d5cb9b4f48095e5166d0d7 *R/nc_att.R
ed86c630397abed4b80fed17eb6b1108 *R/nc_axes.R
a3eac94834c709b542f69dfb0fd89d76 *R/nc_axis.R
c2553fcd2a178fcc69cf45a9d92e3b2e *R/nc_coord.R
d4d32fe919ac0c3b3b2169253f201f24 *R/nc_dim.R
6d5a87799a5ed8c8bcb6c21c0b2f6d3e *R/nc_dimension.R
346849373367b88651b988eecd923cbe *R/nc_grid.R
7fb5a711355999fde006284591f3595f *R/nc_inq_file.R
38d74a29b2ffb5cc6ca0c540ac0b9728 *R/nc_meta.R
cce6e55f8d38433af4e5d9fba0ca8258 *R/nc_sources.R
8c65186e4c478c9a0608d99f9d8f3ef6 *R/nc_var.R
6db823088f12f084a105701725ef5ce2 *R/nc_variable.R
256fc1dcec5e6286bd349b503d6439b4 *R/ncmeta-package.r
d476333edbf533e0c358c8510fbeb9a1 *R/tidync.R
e83c51bf6b2b625df7d7bffce376e7dc *R/utils.R
1e5dbcb7af6f55b471b2b4003b5388e7 *README.md
7244a7e787c300ee1ff9bf8f9f65cb16 *inst/extdata/S2008001.L3b_DAY_CHL.nc
40c384227a7ab68850d78f6f9999b3a9 *inst/extdata/S2008001.L3m_DAY_CHL_chlor_a_9km.nc
b4a46bd6504a4bf94d62327f96ac882b *inst/extdata/avhrr-only-v2.19810901.cdl
0adcd53b4ae24505c08ba21396753c62 *inst/extdata/avhrr-only-v2.19810901_header.nc
05501563f487cf1c550f16dde972b8ca *inst/extdata/daymet_sample.cdl
ca494f6f09d88b8251c5949e717e54b3 *inst/extdata/daymet_sample.nc
8862d147136fc2f79515f0d03c7fd665 *inst/extdata/gridmet_sample.cdl
f3b9bb7b4b9fca435a8a83155bd44241 *inst/extdata/gridmet_sample.nc
ba04746b72066a2695c88dac13253c1b *inst/extdata/guam.nc
03c91523544cdb10c4ffece5125ef575 *inst/extdata/rasterwise-bad_examples_62-example3.cdl
8c0b955fbc005144e7183938a620d193 *inst/extdata/rasterwise-bad_examples_62-example3.nc
2419a64e1d74172935fb2a74fa133fa0 *inst/extdata/rasterwise-high-dim-test-1.cdl
b905e6119236d560c84c74e9eca06838 *inst/extdata/rasterwise-high-dim-test-1.nc
47abac4959216272769a06831d325128 *inst/extdata/rasterwise-timeseries.cdl
98487898a93df7bdf94dd069348b2f26 *inst/extdata/rasterwise-timeseries.nc
b12e9e8139c06da488e80afa56eefb08 *inst/extdata/stars/reduced.nc
f36c760a2e47be4f257e0d457cb5e7a6 *man/nc_att.Rd
9090ddb862fe6d587cc447cdfd6ffeab *man/nc_atts.Rd
47c2c9e01b58f2dc789a81567db0c2c2 *man/nc_axes.Rd
eed87286dc3b5be8903599784e1c3017 *man/nc_axis.Rd
bea48d35a9f68b1fcc37f9fed52ecf6c *man/nc_coord_var.Rd
f3d85457321112f8c90ac381a5227916 *man/nc_dim.Rd
6dd3e0f2b8860d5dfd7555278327baf3 *man/nc_dims.Rd
33bba9f8770ef67fd85c118d4b507478 *man/nc_gm_to_prj.Rd
03af798a4a747976c896aee1638cb033 *man/nc_grid_mapping_atts.Rd
6cffd91e71fa4372668cd24f8f03ab5c *man/nc_grids.Rd
d485004fe8864d3a1b68d9b752d4c348 *man/nc_inq.Rd
d387529944bdab3c3337cd367027ed62 *man/nc_meta.Rd
dbee5af8c23f638a14d0ec698c43d81c *man/nc_prj_to_gridmapping.Rd
81a2ef307ae6881f922a538842511f8c *man/nc_sources.Rd
0b748d0ad245c00d28c062649feb85fb *man/nc_var.Rd
873a23c400185fed242abb4c77680565 *man/nc_vars.Rd
c8db75c2948c26dc44ca76f091f8a355 *man/ncmeta-package.Rd
9da368d8df7c7d2b884589556ff08f18 *tests/testthat.R
cd19b0d576a125f5a15edaf755020aa0 *tests/testthat/test-attributes.R
adf30e688975349de85d6b69fb9f7c8c *tests/testthat/test-coord.R
31f6e2b1e43b8fd3da38b0879c40c961 *tests/testthat/test-dimension.R
27bb733bf578d47148a44d894116ecf0 *tests/testthat/test-file-bogatron.R
f621b0ed3733383bbec8c63fc0493ecc *tests/testthat/test-file-bogeys.R
3f54d82c2e4acc4af7cfb7e579f38394 *tests/testthat/test-file.R
f8ce8bf39bd6a5ca4f0968b70c5e0c93 *tests/testthat/test-grid-var-order.R
6784756e1592abbd65f93949f1ff6bbf *tests/testthat/test-gridmapping-prj.R
d6daa8435b27b5edb4294cbc055f3192 *tests/testthat/test-tidync.R
caedf44f8cf285b0bc2cab6f09e72bc2 *tests/testthat/test-utils.R
85237079a16c479fd35b045d5e66a427 *tests/testthat/test-vars.R
ncmeta/inst/ 0000755 0001762 0000144 00000000000 14520363106 012476 5 ustar ligges users ncmeta/inst/extdata/ 0000755 0001762 0000144 00000000000 14520363106 014130 5 ustar ligges users ncmeta/inst/extdata/daymet_sample.nc 0000644 0001762 0000144 00000004054 14520356511 017303 0 ustar ligges users CDF
time y x
start_year source Daymet Software Version 3.0 Version_software Daymet Software Version 3.0 Version_data Daymet Data Version 3.0 Conventions CF-1.6 citation OPlease see http://daymet.ornl.gov/ for current Daymet data citation information
references OPlease see http://daymet.ornl.gov/ for current information on Daymet references title jDaymet: Daily Surface Weather Data on a 1-km Grid for North America, Version 3 (Continental North America) institution KOak Ridge National Laboratory Distributed Active Archive Center (ORNL DAAC) end_year prcp _CoordinateAxes lat lon time y x
_FillValue <