Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write a group attribute using ncdf4?

Tags:

r

ncdf4

It appears from the ncdf4 documentation (and my trials) that in R, I can define a global attribute by:

ncatt_put(mync,0,'att_name','attribute_text')

I can define a variable attribute in a group by:

ncatt_put(mync,'mygroup/myvar','att_name','attribute_text')

I can get a group attribute not associated by a variable by:

myatt_value<-ncatt_get(mync,'mygroup','att_name')

I have tried each of the following--neither work:

ncatt_put(mync,'mygroup','att_name','attribute_text')
ncatt_put(mync,0,'mygroup/att_name','attribute_text')

How does one write a "global group attribute" in R using ncdf4?

like image 417
kevin Avatar asked Sep 02 '25 04:09

kevin


1 Answers

There is no such thing as a "global group attribute". What netCDF calls a global group is the root group of a hierarchy (even when there are no other groups). Inside a group you can have attributes, dimensions and variables, as well as more groups.

Unfortunately, the ncdf4 package does not fully support groups. Specifically, you cannot create groups, nor refer to their "handle", only by name (as you do above). This is at least somewhat odd because one of the more useful features of netCDF4 over earlier versions is the ability to use groups... You are thus out of luck with ncdf4. You should use the RNetCDF package instead, here demonstrating adding an attribute at all three locations:

library(RNetCDF)

# Make a temporary file
fn <- tempfile(fileext = ".nc")

# Create the netCDF4 file
nc <- create.nc(fn, format = "netcdf4")

# Add a global attribute. Note the use of the nc object here.
# The -1 means "do not attach to a variable but to the group instead"
att.put.nc(nc, -1, "global_attribute", "NC_CHAR", "Data set info")

# Define a group below the root group
# Save the group handle, you'll need it later
grp <- grp.def.nc(nc, "my_group")

# Create a dimension in the root group, use handle nc
d <- dim.def.nc(nc, "global_dim", 3)

# Create a variable in the my_group group, use the grp handle
# You can refer to dimensions higher up in the hierarchy or 
# (re)define them locally
v <- var.def.nc(grp, "group_var", "NC_FLOAT", d)

# Add an attribute to the variable v in group grp
att.put.nc(grp, v, "variable_attribute", "NC_CHAR", "Variable info")

# Now add an attribute to a group. Use the grp handle and -1
# to make it a group attribute
att.put.nc(grp, -1, "group_attribute", "NC_CHAR", "Group info")

# Check the result
print.nc(nc)
#> netcdf netcdf4 {
#> dimensions:
#>  global_dim = 3 ;
#> 
#> // global attributes:
#>      NC_CHAR :global_attribute = "Data set info" ;
#> 
#> group: my_group {
#>   variables:
#>      NC_FLOAT group_var(global_dim) ;
#>          NC_CHAR group_var:variable_attribute = "Variable info" ;
#> 
#>   // group attributes:
#>          NC_CHAR :group_attribute = "Group info" ;
#>   } // group my_group
#> }

# Housekeeping
close.nc(nc)
unlink(fn)

The key is to always use the "handle" that RNetCDF returns from the various functions that create or define objects. I am using "-1" here to attach an attribute at group level - this is identical to using the defined constant "NC_GLOBAL" but that is confusing at group level.

like image 161
Patrick Avatar answered Sep 05 '25 01:09

Patrick