Coverage for src/efts_io/attributes.py: 33.33%
7 statements
« prev ^ index » next coverage.py v7.6.1, created at 2025-07-24 10:14 +1000
« prev ^ index » next coverage.py v7.6.1, created at 2025-07-24 10:14 +1000
1"""Management of netCDF attributes."""
3#' Create variable attribute definition
4#'
5#' Create variable attribute definition
6#'
7#' @param type A data type identifier, as a coded description.
8#' @param type_description description of this data type identifier.
9#' @param location_type a character, type of location, e.g. 'Point'
10#' @param dat_type a character, the type of data stored in this variable
11#' @param dat_type_description a character, human readable description of the data stored in this variable
12#' @export
13#' @return a list of attributes, describing the type of variable stored
14#' @examples
15#' va = create_var_attribute_definition(type=2L,
16#' type_description='accumulated over the preceding interval', location_type='Point')
17#' vdef = create_variable_definition(name='rain_sim',
18#' longname='Rainfall ensemble forecast derived from some prediction',
19#' units='mm', missval=-9999.0, precision='double',
20#' var_attribute=va)
21#'
22from efts_io.conventions import (
23 CATCHMENT_ATTR_KEY,
24 COMMENT_ATTR_KEY,
25 DAT_TYPE_ATTR_KEY,
26 DAT_TYPE_DESCRIPTION_ATTR_KEY,
27 INSTITUTION_ATTR_KEY,
28 LOCATION_TYPE_ATTR_KEY,
29 SOURCE_ATTR_KEY,
30 TITLE_ATTR_KEY,
31 TYPE_ATTR_KEY,
32 TYPE_DESCRIPTION_ATTR_KEY,
33)
36def create_var_attribute_definition(
37 data_type_code: int = 2,
38 type_description: str = "accumulated over the preceding interval",
39 dat_type: str = "der",
40 dat_type_description: str = "AWAP data interpolated from observations",
41 location_type: str = "Point",
42) -> dict[str, str]:
43 """Create variable attribute definition."""
44 return {
45 TYPE_ATTR_KEY: str(data_type_code),
46 TYPE_DESCRIPTION_ATTR_KEY: type_description,
47 DAT_TYPE_ATTR_KEY: dat_type,
48 DAT_TYPE_DESCRIPTION_ATTR_KEY: dat_type_description,
49 LOCATION_TYPE_ATTR_KEY: location_type,
50 }
53# # The following cannot be hard-coded. ncdf4::ncatt_put(nc,0,'institution',
54# # 'CSIRO Land and Water') ncdf4::ncatt_put(nc,0,'comment', '')
55# # ncdf4::ncatt_put(nc,0,'source', '') catchment = paste(letters[1:9],
56# # collapse='') ncdf4::ncatt_put(nc,0,'Catchment', catchment)
57# # ncdf4::ncatt_put(nc,0,'title', paste('Rainfall Observations for',
58# # catchment))
60# #' Add a value to a global attribute of a netCDF file
61# #'
62# #' Add a value to a global attribute of a netCDF file
63# #'
64# #' @param nc an object 'ncdf4'
65# #' @param attribute_name the name of the global attribute to add to
66# #' @param attribute_value the value to pad
67# #' @param sep separator to add between the existing value and the padded value.
68# #' @export
69# #' @import ncdf4
70# pad_global_attribute(nc, attribute_name, attribute_value, sep = "\n") {
71# attVal = ""
72# a = ncdf4::ncatt_get(nc, 0, attribute_name)
73# if (a$hasatt) {
74# attVal = paste(a$value, sep)
75# attVal = paste(attVal, attribute_value)
76# } else {
77# attVal = attribute_value
78# }
79# ncdf4::ncatt_put(nc, 0, attribute_name, as.character(attVal))
80# }
83#' Define a set of global attributes for netCDF files.
84#'
85#' The conventions require a set of global attributes to be present,
86#' see \url{https://github.com/jmp75/efts/blob/master/docs/netcdf_for_water_forecasting.md#global-attributes}.
87#' This function is recommended to define these attributes.
88#'
89#' @param title text, a succinct description of what is in the dataset
90#' @param institution text, Where the original data was produced
91#' @param source text, published or web-based references that describe the data or methods used to produce it
92#' @param catchment text, the catchment for which the data is created. White spaces are replaced with underscores
93#' @param comment text, miscellaneous information
94#' @param strict logical, if true perform extra checks on the input information
95#' @export
96#' @importFrom stringr str_replace_all
97def create_global_attributes(
98 title: str,
99 institution: str,
100 source: str,
101 catchment: str,
102 comment: str,
103) -> dict[str, str]:
104 """Creates STF global attributes.
106 Args:
107 title (str): title
108 institution (str): institution
109 source (str): source
110 catchment (str): catchment
111 comment (str): comment
113 Raises:
114 ValueError: Unexpected or insufficient information
116 Returns:
117 dict[str, str]: _description_
118 """
119 # catchment info should not have white spaces (and why was that???)
120 # catchment = 'Upper Murray River '
121 # catchment = stringr::str_replace_all(catchment, pattern='\\s+', '_')
123 if title == "":
124 raise ValueError("Empty title is not accepted as a valid attribute")
126 return {
127 TITLE_ATTR_KEY: title,
128 INSTITUTION_ATTR_KEY: institution,
129 SOURCE_ATTR_KEY: source,
130 CATCHMENT_ATTR_KEY: catchment,
131 COMMENT_ATTR_KEY: comment,
132 }
135# ########################################
136# # Below are functions not exported
137# ########################################
139# check_global_attributes(nc_attributes)
140# {
141# stopifnot(is.list(nc_attributes))
142# expected = mandatory_global_attributes
143# present_attr = expected %in% names(nc_attributes)
144# missing_attr = which(!present_attr)
145# if(length(missing_attr) > 0) stop(paste("missing global attributes: ",paste(expected[missing_attr], collapse=","), sep=" "))
146# }
148# put_variable_attributes(data_var_def, nc) {
149# a = data_var_def
150# stopifnot("name" %in% names(a))
151# varname = a[["name"]]
152# if ("attributes" %in% names(a)) {
153# attribs = a[["attributes"]]
154# for (attribute_name in names(attribs)) {
155# ncdf4::ncatt_put(nc, varname, attribute_name, attribs[[attribute_name]])
156# }
157# }
158# }