-
Notifications
You must be signed in to change notification settings - Fork 19
/
constructs.py
220 lines (175 loc) · 7.05 KB
/
constructs.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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
import cfdm
from .query import Query
class Constructs(cfdm.Constructs):
'''A container for metadata constructs.
Calling a `Constructs` instance selects metadata constructs by
identity and is an alias for the `filter_by_identity` method.
**Examples:**
Select constructs that have a "standard_name" property of 'latitude':
>>> d = c('latitude')
.. versionadded:: 3.0.0
'''
def __repr__(self):
'''Called by the `repr` built-in function.
x.__repr__() <==> repr(x)
'''
return super().__repr__().replace('<', '<CF ', 1)
def _matching_values(self, value0, construct, value1):
'''TODO
'''
if isinstance(value0, Query):
return value0.evaluate(value1)
return super()._matching_values(value0, construct, value1)
# def domain_axis_key(self, identity, default=ValueError()):
# '''Return the key of the domain axis construct that is spanned by 1-d
# coordinate constructs.
#
# .. versionadded:: 3.0.0
#
# :Parameters:
#
# identity:
#
# Select the 1-d coordinate constructs that have the given
# identity.
#
# An identity is specified by a string (e.g. ``'latitude'``,
# ``'long_name=time'``, etc.); or a compiled regular expression
# (e.g. ``re.compile('^atmosphere')``), for which all constructs
# whose identities match (via `re.search`) are selected.
#
# Each coordinate construct has a number of identities, and is
# selected if any of them match any of those provided. A
# construct's identities are those returned by its `!identities`
# method. In the following example, the construct ``x`` has four
# identities:
#
# >>> x.identities()
# ['time', 'long_name=Time', 'foo=bar', 'ncvar%T']
#
# In addition, each construct also has an identity based its
# construct key (e.g. ``'key%dimensioncoordinate2'``)
#
# Note that in the output of a `print` call or `!dump` method, a
# construct is always described by one of its identities, and so
# this description may always be used as an *identity* argument.
#
# default: optional
# Return the value of the *default* parameter if a domain axis
# construct can not be found. If set to an `Exception` instance
# then it will be raised instead.
#
# :Returns:
#
# `str`
# The key of the domain axis construct that is spanned by the
# data of the selected 1-d coordinate constructs.
#
# **Examples:**
#
# TODO
#
# '''
# # Try for index
# try:
# da_key = self.get_data_axes(default=None)[identity]
# except TypeError:
# pass
# except IndexError:
# return self._default(
# default,
# "Index does not exist for field construct data dimenions")
# else:
# identity = da_key
#
# domain_axes = self.domain_axes(identity)
# if len(domain_axes) == 1:
# # identity is a unique domain axis construct identity
# da_key = domain_axes.key()
# else:
# # identity is not a unique domain axis construct identity
# da_key = self.domain_axis_key(identity, default=default)
#
# if key:
# return da_key
#
# return self.constructs[da_key]
def filter_by_identity(self, *identities):
'''Select metadata constructs by identity.
.. versionadded:: 3.0.0
.. seealso:: `filter_by_axis`, `filter_by_data`, `filter_by_key`,
`filter_by_measure`, `filter_by_method`,
`filter_by_naxes`, `filter_by_ncdim`,
`filter_by_ncvar`, `filter_by_property`,
`filter_by_size`, `filter_by_type`,
`filters_applied`, `inverse_filter`, `unfilter`
:Parameters:
identities: optional
Select constructs that have any of the given identities or
construct keys.
An identity is specified by a string (e.g. ``'latitude'``,
``'long_name=time'``, etc.); or a compiled regular
expression (e.g. ``re.compile('^atmosphere')``), for which
all constructs whose identities match (via `re.search`)
are selected.
If no identities are provided then all constructs are selected.
Each construct has a number of identities, and is selected
if any of them match any of those provided. A construct's
identities are those returned by its `!identities`
method. In the following example, the construct ``x`` has
five identities:
>>> x.identities()
['time', 'long_name=Time', 'foo=bar', 'T', 'ncvar%t']
A construct key may optionally have the ``'key%'``
prefix. For example ``'dimensioncoordinate2'`` and
``'key%dimensioncoordinate2'`` are both acceptable keys.
Note that the identifiers of a metadata construct in the
output of a `print` or `!dump` call are always one of its
identities, and so may always be used as an *identities*
argument.
Domain axis constructs may also be identified by their
position in the field construct's data array. Positions
are specified by either integers.
.. note:: This is an extension to the functionality of
`cfdm.Constucts.filter_by_identity`.
:Returns:
`Constructs`
The selected constructs and their construct keys.
**Examples:**
Select constructs that have a "standard_name" property of
'latitude':
>>> d = c.filter_by_identity('latitude')
Select constructs that have a "long_name" property of 'Height':
>>> d = c.filter_by_identity('long_name=Height')
Select constructs that have a "standard_name" property of
'latitude' or a "foo" property of 'bar':
>>> d = c.filter_by_identity('latitude', 'foo=bar')
Select constructs that have a netCDF variable name of 'time':
>>> d = c.filter_by_identity('ncvar%time')
'''
# field_data_axes = self._field_data_axes
#
# if field_data_axes is not None:
# # Allows integer data domain axis positions, do we want this? TODO
# new_identities = []
# for i in identities:
# try:
# _ = field_data_axes[i]
# except IndexError:
# new_identities.append(i)
# else:
# if isinstance(_, str):
# new_identities.append('key%'+_)
# else:
# new_identities.extend(['key%'+axis for axis in _])
# else:
# new_identities = identities
#
# Allow keys without the 'key%' prefix
identities = list(identities)
for n, identity in enumerate(identities):
if identity in self:
identities[n] = 'key%'+identity
# --- End: for
return super().filter_by_identity(*identities)
# --- End: class