cfapyx 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
cfapyx/__init__.py ADDED
@@ -0,0 +1,3 @@
1
+ from .backend import CFANetCDFBackendEntrypoint as CFANetCDFBackendEntrypoint
2
+ from .creator import CFANetCDF as CFANetCDF
3
+ from .utils import set_verbose as set_verbose
cfapyx/backend.py ADDED
@@ -0,0 +1,181 @@
1
+ __author__ = "Daniel Westwood"
2
+ __contact__ = "daniel.westwood@stfc.ac.uk"
3
+ __copyright__ = "Copyright 2024 United Kingdom Research and Innovation"
4
+
5
+ import logging
6
+
7
+ from xarray import conventions
8
+ from xarray.backends import BackendEntrypoint, StoreBackendEntrypoint
9
+ from xarray.backends.common import AbstractDataStore
10
+ from xarray.core.dataset import Dataset
11
+
12
+ from cfapyx.datastore import CFADataStore
13
+ from cfapyx.utils import logstream
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+ logger.addHandler(logstream)
18
+ logger.propagate = False
19
+
20
+
21
+ def open_cfa_dataset(
22
+ filename_or_obj,
23
+ drop_variables=None,
24
+ mask_and_scale=False,
25
+ decode_times=True,
26
+ concat_characters=None,
27
+ decode_coords=None,
28
+ use_cftime=None,
29
+ decode_timedelta=None,
30
+ cfa_options: dict = None,
31
+ group=None,
32
+ ):
33
+ """
34
+ Top-level function which opens a CFA dataset using Xarray.
35
+
36
+ Creates a CFA Datastore
37
+ from the ``filename_or_obj`` provided, then passes this to a CFA
38
+ StoreBackendEntrypoint to create an Xarray Dataset. Most parameters are
39
+ not handled by CFA, so only the CFA-relevant ones are described here.
40
+
41
+ :param filename_or_obj: (str) The path to a CFA-netCDF file to be
42
+ opened by Xarray
43
+
44
+ :param cfa_options: (dict) A set of kwargs provided to CFA which
45
+ provide additional configurations. Currently implemented are:
46
+ substitutions (dict), decode_cfa (bool)
47
+
48
+ :param group: (str) The name or path to a NetCDF group.
49
+ CFA can handle opening from specific groups and will inherit both
50
+ ``group`` and ``global`` dimensions/attributes.
51
+
52
+ :returns: An xarray.Dataset object composed of xarray.DataArray objects
53
+ representing the different NetCDF variables and dimensions. CFA aggregated
54
+ variables are decoded unless the ``decode_cfa`` parameter in ``cfa_options``
55
+ is false.
56
+ """
57
+
58
+ cfa_options = cfa_options or {}
59
+
60
+ # Load the CFA datastore from the provided file (object not supported).
61
+ store = CFADataStore.open(filename_or_obj, group=group)
62
+
63
+ # Expands cfa_options into individual kwargs for the store.
64
+ store.cfa_options = cfa_options
65
+ # Mask/scale decoding now done internally.
66
+ store.mask_and_scale = mask_and_scale
67
+
68
+ # Xarray makes use of StoreBackendEntrypoints to provide the Dataset 'ds'
69
+ store_entrypoint = CFAStoreBackendEntrypoint()
70
+ ds = store_entrypoint.open_dataset(
71
+ store,
72
+ decode_times=decode_times,
73
+ concat_characters=concat_characters,
74
+ decode_coords=decode_coords,
75
+ drop_variables=drop_variables,
76
+ use_cftime=use_cftime,
77
+ decode_timedelta=decode_timedelta,
78
+ )
79
+
80
+ return ds
81
+
82
+
83
+ class CFANetCDFBackendEntrypoint(BackendEntrypoint):
84
+ """Open CFA-netCDF files (.nca) using 'cfapyx' in Xarray"""
85
+
86
+ description = 'Open CFA-netCDF files (.nca) using "cfapyx" in Xarray'
87
+ url = "https://cedadev.github.io/CFAPyX/"
88
+
89
+ def open_dataset(
90
+ self,
91
+ filename_or_obj,
92
+ *,
93
+ drop_variables=None,
94
+ mask_and_scale=False,
95
+ decode_times=True,
96
+ concat_characters=None,
97
+ decode_coords=None,
98
+ use_cftime=None,
99
+ decode_timedelta=None,
100
+ cfa_options=None,
101
+ group=None,
102
+ # backend specific keyword arguments
103
+ # do not use 'chunks' or 'cache' here
104
+ ):
105
+ """
106
+ Returns a complete xarray representation of a CFA-netCDF dataset which
107
+ includes expanding/decoding CFA aggregated variables into proper arrays.
108
+ """
109
+
110
+ cfa_options = cfa_options or {}
111
+
112
+ return open_cfa_dataset(
113
+ filename_or_obj,
114
+ drop_variables=drop_variables,
115
+ mask_and_scale=mask_and_scale,
116
+ decode_times=decode_times,
117
+ concat_characters=concat_characters,
118
+ decode_coords=decode_coords,
119
+ use_cftime=use_cftime,
120
+ decode_timedelta=decode_timedelta,
121
+ cfa_options=cfa_options,
122
+ group=group,
123
+ )
124
+
125
+
126
+ class CFAStoreBackendEntrypoint(StoreBackendEntrypoint):
127
+ """Open CFA-based Abstract Data Store"""
128
+
129
+ description = "Open CFA-based Abstract Data Store"
130
+ url = "https://cedadev.github.io/CFAPyX/"
131
+
132
+ def open_dataset(
133
+ self,
134
+ cfa_xarray_store,
135
+ decode_times=True,
136
+ concat_characters=True,
137
+ decode_coords=True,
138
+ drop_variables=None,
139
+ use_cftime=None,
140
+ decode_timedelta=None,
141
+ ) -> Dataset:
142
+ """
143
+ Takes cfa_xarray_store of type AbstractDataStore and creates an
144
+ xarray.Dataset object. Most parameters are not handled by CFA, so only the
145
+ CFA-relevant ones are described here.
146
+
147
+ :param cfa_xarray_store: (obj) The CFA Datastore object which
148
+ loads and decodes CFA aggregated variables and dimensions.
149
+
150
+ :returns: An xarray.Dataset object composed of xarray.DataArray
151
+ objects representing the different NetCDF variables and dimensions.
152
+ CFA aggregated variables are decoded unless the ``decode_cfa``
153
+ parameter in ``cfa_options`` is false.
154
+
155
+ """
156
+ assert isinstance(cfa_xarray_store, AbstractDataStore)
157
+
158
+ # Same as NetCDF4 operations, just with the CFA Datastore
159
+ vars, attrs = cfa_xarray_store.load()
160
+ encoding = cfa_xarray_store.get_encoding()
161
+
162
+ # Ensures variables/attributes comply with CF conventions.
163
+ vars, attrs, coord_names = conventions.decode_cf_variables(
164
+ vars,
165
+ attrs,
166
+ decode_times=decode_times,
167
+ concat_characters=concat_characters,
168
+ decode_coords=decode_coords,
169
+ drop_variables=drop_variables,
170
+ use_cftime=use_cftime,
171
+ decode_timedelta=decode_timedelta,
172
+ )
173
+
174
+ # Create the xarray.Dataset object here.
175
+ ds = Dataset(vars, attrs=attrs)
176
+
177
+ ds = ds.set_coords(coord_names.intersection(vars))
178
+ ds.set_close(cfa_xarray_store.close)
179
+ ds.encoding = encoding
180
+
181
+ return ds