-
Notifications
You must be signed in to change notification settings - Fork 41
/
Copy pathtracking.py
87 lines (71 loc) · 2.53 KB
/
tracking.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# This module provides functions for adding CF attribtues
# and tracking history, provenance using xarray's keep_attrs
# functionality
import copy
import functools
from datetime import datetime
CELL_METHODS = {
"sum": "sum",
"max": "maximum",
"min": "minimum",
"median": "median",
"mean": "mean",
"std": "standard_deviation",
"var": "variance",
}
def add_cell_methods(attrs, context):
"""Add appropriate cell_methods attribute."""
assert len(attrs) == 1
cell_methods = attrs[0].get("cell_methods", "")
# TODO: get dim_name from context
return {"cell_methods": f"dim_name: {CELL_METHODS[context.func]} {cell_methods}"}
def add_history(attrs, context):
"""Adds a history attribute following the NetCDF User Guide convention."""
# https://www.unidata.ucar.edu/software/netcdf/documentation/4.7.4-pre/attribute_conventions.html
# A global attribute for an audit trail. This is a character array with a line
# for each invocation of a program that has modified the dataset. Well-behaved
# generic netCDF applications should append a line containing:
# date, time of day, user name, program name and command arguments.
# nco uses the ctime format
now = datetime.now().ctime()
history = attrs[0].get("history", [])
new_history = (
f"{now}:"
f" {context.func}(args)\n"
# TODO: should we record software versions?
)
return {"history": history + [new_history]}
def _tracker(
attrs,
context,
strict: bool = False,
cell_methods: bool = True,
history: bool = True,
):
# can only handle single variable attrs for now
assert len(attrs) == 1
attrs_out = copy.deepcopy(attrs[0])
if cell_methods and context.func in CELL_METHODS:
attrs_out.update(add_cell_methods(attrs, context))
if history:
attrs_out.update(add_history(attrs, context))
pass
return attrs_out
def track_cf_attributes(
*, strict: bool = False, cell_methods: bool = True, history: bool = True
):
"""Top-level user-facing function.
Parameters
----------
strict: bool
Controls if an error is raised when an appropriate attribute cannot
be added because of lack of information.
cell_methods: bool
Add cell_methods attribute when possible
history: bool
Adds a history attribute like NCO and follows the NUG convention.
"""
# TODO: check xarray version here.
return functools.partial(
_tracker, strict=strict, cell_methods=cell_methods, history=history
)