vortex-nwp 2.0.0b1__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.
- vortex/__init__.py +135 -0
- vortex/algo/__init__.py +12 -0
- vortex/algo/components.py +2136 -0
- vortex/algo/mpitools.py +1648 -0
- vortex/algo/mpitools_templates/envelope_wrapper_default.tpl +27 -0
- vortex/algo/mpitools_templates/envelope_wrapper_mpiauto.tpl +29 -0
- vortex/algo/mpitools_templates/wrapstd_wrapper_default.tpl +18 -0
- vortex/algo/serversynctools.py +170 -0
- vortex/config.py +115 -0
- vortex/data/__init__.py +13 -0
- vortex/data/abstractstores.py +1572 -0
- vortex/data/containers.py +780 -0
- vortex/data/contents.py +596 -0
- vortex/data/executables.py +284 -0
- vortex/data/flow.py +113 -0
- vortex/data/geometries.ini +2689 -0
- vortex/data/geometries.py +703 -0
- vortex/data/handlers.py +1021 -0
- vortex/data/outflow.py +67 -0
- vortex/data/providers.py +465 -0
- vortex/data/resources.py +201 -0
- vortex/data/stores.py +1271 -0
- vortex/gloves.py +282 -0
- vortex/layout/__init__.py +27 -0
- vortex/layout/appconf.py +109 -0
- vortex/layout/contexts.py +511 -0
- vortex/layout/dataflow.py +1069 -0
- vortex/layout/jobs.py +1276 -0
- vortex/layout/monitor.py +833 -0
- vortex/layout/nodes.py +1424 -0
- vortex/layout/subjobs.py +464 -0
- vortex/nwp/__init__.py +11 -0
- vortex/nwp/algo/__init__.py +12 -0
- vortex/nwp/algo/assim.py +483 -0
- vortex/nwp/algo/clim.py +920 -0
- vortex/nwp/algo/coupling.py +609 -0
- vortex/nwp/algo/eda.py +632 -0
- vortex/nwp/algo/eps.py +613 -0
- vortex/nwp/algo/forecasts.py +745 -0
- vortex/nwp/algo/fpserver.py +927 -0
- vortex/nwp/algo/ifsnaming.py +403 -0
- vortex/nwp/algo/ifsroot.py +311 -0
- vortex/nwp/algo/monitoring.py +202 -0
- vortex/nwp/algo/mpitools.py +554 -0
- vortex/nwp/algo/odbtools.py +974 -0
- vortex/nwp/algo/oopsroot.py +735 -0
- vortex/nwp/algo/oopstests.py +186 -0
- vortex/nwp/algo/request.py +579 -0
- vortex/nwp/algo/stdpost.py +1285 -0
- vortex/nwp/data/__init__.py +12 -0
- vortex/nwp/data/assim.py +392 -0
- vortex/nwp/data/boundaries.py +261 -0
- vortex/nwp/data/climfiles.py +539 -0
- vortex/nwp/data/configfiles.py +149 -0
- vortex/nwp/data/consts.py +929 -0
- vortex/nwp/data/ctpini.py +133 -0
- vortex/nwp/data/diagnostics.py +181 -0
- vortex/nwp/data/eda.py +148 -0
- vortex/nwp/data/eps.py +383 -0
- vortex/nwp/data/executables.py +1039 -0
- vortex/nwp/data/fields.py +96 -0
- vortex/nwp/data/gridfiles.py +308 -0
- vortex/nwp/data/logs.py +551 -0
- vortex/nwp/data/modelstates.py +334 -0
- vortex/nwp/data/monitoring.py +220 -0
- vortex/nwp/data/namelists.py +644 -0
- vortex/nwp/data/obs.py +748 -0
- vortex/nwp/data/oopsexec.py +72 -0
- vortex/nwp/data/providers.py +182 -0
- vortex/nwp/data/query.py +217 -0
- vortex/nwp/data/stores.py +147 -0
- vortex/nwp/data/surfex.py +338 -0
- vortex/nwp/syntax/__init__.py +9 -0
- vortex/nwp/syntax/stdattrs.py +375 -0
- vortex/nwp/tools/__init__.py +10 -0
- vortex/nwp/tools/addons.py +35 -0
- vortex/nwp/tools/agt.py +55 -0
- vortex/nwp/tools/bdap.py +48 -0
- vortex/nwp/tools/bdcp.py +38 -0
- vortex/nwp/tools/bdm.py +21 -0
- vortex/nwp/tools/bdmp.py +49 -0
- vortex/nwp/tools/conftools.py +1311 -0
- vortex/nwp/tools/drhook.py +62 -0
- vortex/nwp/tools/grib.py +268 -0
- vortex/nwp/tools/gribdiff.py +99 -0
- vortex/nwp/tools/ifstools.py +163 -0
- vortex/nwp/tools/igastuff.py +249 -0
- vortex/nwp/tools/mars.py +56 -0
- vortex/nwp/tools/odb.py +548 -0
- vortex/nwp/tools/partitioning.py +234 -0
- vortex/nwp/tools/satrad.py +56 -0
- vortex/nwp/util/__init__.py +6 -0
- vortex/nwp/util/async.py +184 -0
- vortex/nwp/util/beacon.py +40 -0
- vortex/nwp/util/diffpygram.py +359 -0
- vortex/nwp/util/ens.py +198 -0
- vortex/nwp/util/hooks.py +128 -0
- vortex/nwp/util/taskdeco.py +81 -0
- vortex/nwp/util/usepygram.py +591 -0
- vortex/nwp/util/usetnt.py +87 -0
- vortex/proxy.py +6 -0
- vortex/sessions.py +341 -0
- vortex/syntax/__init__.py +9 -0
- vortex/syntax/stdattrs.py +628 -0
- vortex/syntax/stddeco.py +176 -0
- vortex/toolbox.py +982 -0
- vortex/tools/__init__.py +11 -0
- vortex/tools/actions.py +457 -0
- vortex/tools/addons.py +297 -0
- vortex/tools/arm.py +76 -0
- vortex/tools/compression.py +322 -0
- vortex/tools/date.py +20 -0
- vortex/tools/ddhpack.py +10 -0
- vortex/tools/delayedactions.py +672 -0
- vortex/tools/env.py +513 -0
- vortex/tools/folder.py +663 -0
- vortex/tools/grib.py +559 -0
- vortex/tools/lfi.py +746 -0
- vortex/tools/listings.py +354 -0
- vortex/tools/names.py +575 -0
- vortex/tools/net.py +1790 -0
- vortex/tools/odb.py +10 -0
- vortex/tools/parallelism.py +336 -0
- vortex/tools/prestaging.py +186 -0
- vortex/tools/rawfiles.py +10 -0
- vortex/tools/schedulers.py +413 -0
- vortex/tools/services.py +871 -0
- vortex/tools/storage.py +1061 -0
- vortex/tools/surfex.py +61 -0
- vortex/tools/systems.py +3396 -0
- vortex/tools/targets.py +384 -0
- vortex/util/__init__.py +9 -0
- vortex/util/config.py +1071 -0
- vortex/util/empty.py +24 -0
- vortex/util/helpers.py +184 -0
- vortex/util/introspection.py +63 -0
- vortex/util/iosponge.py +76 -0
- vortex/util/roles.py +51 -0
- vortex/util/storefunctions.py +103 -0
- vortex/util/structs.py +26 -0
- vortex/util/worker.py +150 -0
- vortex_nwp-2.0.0b1.dist-info/LICENSE +517 -0
- vortex_nwp-2.0.0b1.dist-info/METADATA +50 -0
- vortex_nwp-2.0.0b1.dist-info/RECORD +146 -0
- vortex_nwp-2.0.0b1.dist-info/WHEEL +5 -0
- vortex_nwp-2.0.0b1.dist-info/top_level.txt +1 -0
vortex/tools/names.py
ADDED
|
@@ -0,0 +1,575 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Functions and tools to handle resources names or other kind of names.
|
|
3
|
+
|
|
4
|
+
Any "name building" object, must conform to the :class:`AbstractVortexNameBuilder`
|
|
5
|
+
abstract class interface.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from bronx.fancies import loggers
|
|
9
|
+
import footprints
|
|
10
|
+
from footprints import proxy as fpx
|
|
11
|
+
|
|
12
|
+
#: No automatic export
|
|
13
|
+
__all__ = []
|
|
14
|
+
|
|
15
|
+
logger = loggers.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class VortexNameBuilderError(ValueError):
|
|
19
|
+
"""Raised whenever the name building process fails."""
|
|
20
|
+
pass
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class AbstractVortexNameBuilder(footprints.FootprintBase):
|
|
24
|
+
"""Abstract class for any name building class."""
|
|
25
|
+
|
|
26
|
+
_abstract = True
|
|
27
|
+
_collector = ('vortexnamebuilder',)
|
|
28
|
+
_footprint = dict(
|
|
29
|
+
info = 'Abstract Vortex NameBuilder',
|
|
30
|
+
attr = dict(
|
|
31
|
+
name = dict(
|
|
32
|
+
info = "The NameBuilder's name.",
|
|
33
|
+
),
|
|
34
|
+
),
|
|
35
|
+
fastkeys = {'name'}
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
def __init__(self, *args, **kw):
|
|
39
|
+
logger.debug('Init VortexNameBuilder %s', self.__class__)
|
|
40
|
+
super().__init__(*args, **kw)
|
|
41
|
+
self._default = dict(
|
|
42
|
+
radical='vortexdata',
|
|
43
|
+
)
|
|
44
|
+
# List of known defaults
|
|
45
|
+
for k in ['flow', 'src', 'term', 'period', 'cen_period', 'geo', 'suffix',
|
|
46
|
+
'stage', 'fmt', 'part', 'compute', 'number', 'filtername']:
|
|
47
|
+
self._default[k] = None
|
|
48
|
+
self.setdefault(**kw)
|
|
49
|
+
|
|
50
|
+
def setdefault(self, **kw):
|
|
51
|
+
"""Update or set new default values as the background description used in packing."""
|
|
52
|
+
self._default.update(kw)
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def defaults(self):
|
|
56
|
+
"""List of currently declared defaults (defined or not)."""
|
|
57
|
+
return self._default.keys()
|
|
58
|
+
|
|
59
|
+
def as_dump(self):
|
|
60
|
+
"""Nicely formated view of the current class in dump context."""
|
|
61
|
+
return str(self._default)
|
|
62
|
+
|
|
63
|
+
def pack(self, d):
|
|
64
|
+
"""A shortcut to :meth:`pack_basename` (legacy)."""
|
|
65
|
+
return self.pack_basename(d)
|
|
66
|
+
|
|
67
|
+
def pack_basename(self, d):
|
|
68
|
+
"""Returns a basename given the **d** info dictionary."""
|
|
69
|
+
raise NotImplementedError('This is an abstract method !')
|
|
70
|
+
|
|
71
|
+
def pack_pathname(self, d):
|
|
72
|
+
"""Returns a pathname given the **d** info dictionary."""
|
|
73
|
+
raise NotImplementedError('This is an abstract method !')
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
# Activate the footprint's fasttrack on the resources collector
|
|
77
|
+
vbcollect = footprints.collectors.get(tag='vortexnamebuilder')
|
|
78
|
+
vbcollect.fasttrack = ('name', )
|
|
79
|
+
del vbcollect
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class AbstractVortexNameBuilderProxy(AbstractVortexNameBuilder):
|
|
83
|
+
"""Abstract class for any "proxy" builder object.
|
|
84
|
+
|
|
85
|
+
Given the input dictionary, find the appropriate builder object and delegate
|
|
86
|
+
the work.
|
|
87
|
+
"""
|
|
88
|
+
|
|
89
|
+
_abstract = True
|
|
90
|
+
|
|
91
|
+
def __init__(self, *kargs, **kwargs):
|
|
92
|
+
# Cache for actual builder objects
|
|
93
|
+
self._instanciated_builders = dict()
|
|
94
|
+
super().__init__(*kargs, **kwargs)
|
|
95
|
+
|
|
96
|
+
def setdefault(self, **kw):
|
|
97
|
+
"""Update or set new default values as the background description used in packing."""
|
|
98
|
+
self._default.update(kw)
|
|
99
|
+
for builder in self._instanciated_builders.values():
|
|
100
|
+
builder.setdefault(**kw)
|
|
101
|
+
|
|
102
|
+
def _get_builder(self, name):
|
|
103
|
+
"""Return a builder object given a name.
|
|
104
|
+
|
|
105
|
+
A cache is used in order for faster computations.
|
|
106
|
+
"""
|
|
107
|
+
if name not in self._instanciated_builders:
|
|
108
|
+
builder = fpx.vortexnamebuilder(name=name)
|
|
109
|
+
if self._default:
|
|
110
|
+
builder.setdefault(**self._default)
|
|
111
|
+
self._instanciated_builders[name] = builder
|
|
112
|
+
return self._instanciated_builders[name]
|
|
113
|
+
|
|
114
|
+
def _pick_actual_builder(self, d):
|
|
115
|
+
"""Given the input dictionary, returns the appropriate builder object."""
|
|
116
|
+
raise NotImplementedError('This is an abstract method !')
|
|
117
|
+
|
|
118
|
+
def pack_basename(self, d):
|
|
119
|
+
"""Returns a basename given the **d** info dictionary."""
|
|
120
|
+
components = dict()
|
|
121
|
+
components.update(self._default)
|
|
122
|
+
components.update(d)
|
|
123
|
+
return self._pick_actual_builder(components).pack_basename(d)
|
|
124
|
+
|
|
125
|
+
def pack_pathname(self, d):
|
|
126
|
+
"""Returns a pathname given the **d** info dictionary."""
|
|
127
|
+
components = dict()
|
|
128
|
+
components.update(self._default)
|
|
129
|
+
components.update(d)
|
|
130
|
+
return self._pick_actual_builder(components).pack_pathname(d)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class AbstractActualVortexNameBuilder(AbstractVortexNameBuilder):
|
|
134
|
+
"""Abstract class for any "concrete" builder object (as opposed to proxies)."""
|
|
135
|
+
|
|
136
|
+
_abstract = True
|
|
137
|
+
|
|
138
|
+
def _pack_generic(self, d, what, default='std'):
|
|
139
|
+
"""
|
|
140
|
+
Build the resource vortex basename/pathname or whatever according to
|
|
141
|
+
``style`` value.
|
|
142
|
+
"""
|
|
143
|
+
components = dict()
|
|
144
|
+
components.update(self._default)
|
|
145
|
+
components.update(d)
|
|
146
|
+
|
|
147
|
+
packstyle = getattr(self, '_pack_{!s}_{!s}'.format(what,
|
|
148
|
+
components.get('style', default)))
|
|
149
|
+
return packstyle(components)
|
|
150
|
+
|
|
151
|
+
def pack_basename(self, d):
|
|
152
|
+
"""Build the resource vortex basename according to ``style`` value."""
|
|
153
|
+
return self._pack_generic(d, 'basename')
|
|
154
|
+
|
|
155
|
+
def pack_pathname(self, d):
|
|
156
|
+
"""Build the resource vortex pathname according to ``style`` value."""
|
|
157
|
+
return '/'.join(self._pack_generic(d, 'pathname'))
|
|
158
|
+
|
|
159
|
+
# A Vortex pathname may include the following bits
|
|
160
|
+
|
|
161
|
+
def _pack_pathname_init(self, d):
|
|
162
|
+
"""Mandatory things to be packed into the pathname."""
|
|
163
|
+
pathbits = []
|
|
164
|
+
for k in ['vapp', 'vconf', 'experiment']:
|
|
165
|
+
if k not in d:
|
|
166
|
+
raise VortexNameBuilderError('The {!r} info key is mandatory'.format(k))
|
|
167
|
+
pathbits.append(str(d[k]))
|
|
168
|
+
return pathbits
|
|
169
|
+
|
|
170
|
+
def _pack_pathname_append_flowdate(self, pathbits, d):
|
|
171
|
+
"""Pack the date/cutoff that characterise the resource's flow."""
|
|
172
|
+
if 'flow' in d and d['flow'] is not None:
|
|
173
|
+
pathbits.append(self._pack_std_items_datestuff(d['flow'], fatal=True))
|
|
174
|
+
else:
|
|
175
|
+
raise VortexNameBuilderError('The flow info key is mandatory')
|
|
176
|
+
|
|
177
|
+
def _pack_pathname_append_flowperiod(self, pathbits, d):
|
|
178
|
+
"""Pack the period/cutoff that characterise the resource's flow."""
|
|
179
|
+
if 'flow' in d and d['flow'] is not None:
|
|
180
|
+
pathbits.append(self._pack_std_items_periodstuff(d['flow'], fatal=True))
|
|
181
|
+
else:
|
|
182
|
+
raise VortexNameBuilderError('The flow info key is mandatory')
|
|
183
|
+
|
|
184
|
+
def _pack_pathname_append_member(self, pathbits, d):
|
|
185
|
+
"""Pack the provider's member number (optional)."""
|
|
186
|
+
if 'member' in d and d['member'] is not None:
|
|
187
|
+
pathbits.append(self._pack_std_item_member(d['member']))
|
|
188
|
+
|
|
189
|
+
def _pack_pathname_append_scenario(self, pathbits, d):
|
|
190
|
+
"""Pack the provider's scenario identifier (optional)."""
|
|
191
|
+
if 'scenario' in d and d['scenario'] is not None:
|
|
192
|
+
pathbits.append(self._pack_std_item_scenario(d['scenario']))
|
|
193
|
+
|
|
194
|
+
def _pack_pathname_append_block(self, pathbits, d):
|
|
195
|
+
"""Pack the provider's block name."""
|
|
196
|
+
if 'block' in d:
|
|
197
|
+
if d['block']:
|
|
198
|
+
pathbits.append('_'.join(self._pack_std_items(d['block'])))
|
|
199
|
+
else:
|
|
200
|
+
raise VortexNameBuilderError('The block info key is mandatory')
|
|
201
|
+
|
|
202
|
+
# A bunch of utility methods that prepares values
|
|
203
|
+
|
|
204
|
+
def _pack_void_item(self, value):
|
|
205
|
+
"""The most trivial conversion mechanism: the ``value`` as string."""
|
|
206
|
+
return str(value)
|
|
207
|
+
|
|
208
|
+
def _pack_std_item_seta(self, value):
|
|
209
|
+
"""Packing of a MPI-task number in first direction."""
|
|
210
|
+
return 'a{:04d}'.format(int(value))
|
|
211
|
+
|
|
212
|
+
def _pack_std_item_setb(self, value):
|
|
213
|
+
"""Packing of a MPI-task number in second direction."""
|
|
214
|
+
return 'b{:04d}'.format(int(value))
|
|
215
|
+
|
|
216
|
+
def _pack_std_item_mpi(self, value):
|
|
217
|
+
"""Packing of a MPI-task number."""
|
|
218
|
+
return 'n{:04d}'.format(int(value))
|
|
219
|
+
|
|
220
|
+
def _pack_std_item_openmp(self, value):
|
|
221
|
+
"""Packing of an OpenMP id number."""
|
|
222
|
+
return 'omp{:02d}'.format(int(value))
|
|
223
|
+
|
|
224
|
+
def _pack_std_item_month(self, value):
|
|
225
|
+
"""Packing of a month-number value."""
|
|
226
|
+
return 'm{!s}'.format(value)
|
|
227
|
+
|
|
228
|
+
def _pack_std_item_stretching(self, value):
|
|
229
|
+
"""Packing of the stretching factor in spectral geometry."""
|
|
230
|
+
return 'c{!s}'.format(int(value * 10))
|
|
231
|
+
|
|
232
|
+
def _pack_std_item_truncation(self, value):
|
|
233
|
+
"""Packing of the geometry's truncation value."""
|
|
234
|
+
if isinstance(value, tuple):
|
|
235
|
+
return 't{1:s}{2:s}{0!s}'.format(* value)
|
|
236
|
+
else:
|
|
237
|
+
return 'tl{!s}'.format(value)
|
|
238
|
+
|
|
239
|
+
def _pack_std_item_filtering(self, value):
|
|
240
|
+
"""Packing of the geometry's filtering value."""
|
|
241
|
+
return 'f{!s}'.format(value)
|
|
242
|
+
|
|
243
|
+
def _pack_std_item_time(self, value):
|
|
244
|
+
"""Packing of a Time object."""
|
|
245
|
+
return value.fmthm if hasattr(value, 'fmthm') else str(value)
|
|
246
|
+
|
|
247
|
+
_pack_std_item_begintime = _pack_std_item_time
|
|
248
|
+
_pack_std_item_endtime = _pack_std_item_time
|
|
249
|
+
|
|
250
|
+
def _pack_std_item_date(self, value):
|
|
251
|
+
"""Packing of a Time object."""
|
|
252
|
+
return value.stdvortex if hasattr(value, 'stdvortex') else str(value)
|
|
253
|
+
|
|
254
|
+
_pack_std_item_begindate = _pack_std_item_date
|
|
255
|
+
_pack_std_item_enddate = _pack_std_item_date
|
|
256
|
+
|
|
257
|
+
def _pack_std_item_cutoff(self, value):
|
|
258
|
+
"""Abbreviate the cutoff name."""
|
|
259
|
+
cutoff_map = dict(production='prod')
|
|
260
|
+
return cutoff_map.get(value, value)
|
|
261
|
+
|
|
262
|
+
def _pack_std_item_shortcutoff(self, value, default='X'):
|
|
263
|
+
"""Abbreviate the cutoff name."""
|
|
264
|
+
return value[0].upper() if value is not None else default
|
|
265
|
+
|
|
266
|
+
def _pack_std_item_member(self, value):
|
|
267
|
+
return 'mb{:03d}'.format(value)
|
|
268
|
+
|
|
269
|
+
def _pack_std_item_scenario(self, value):
|
|
270
|
+
return 's{:s}'.format(value)
|
|
271
|
+
|
|
272
|
+
def _pack_std_items(self, items):
|
|
273
|
+
"""
|
|
274
|
+
Go through all items and pack them according to the so-called standard way.
|
|
275
|
+
Result is always a list of string values.
|
|
276
|
+
"""
|
|
277
|
+
if not isinstance(items, list):
|
|
278
|
+
items = [items]
|
|
279
|
+
packed = list()
|
|
280
|
+
for i in items:
|
|
281
|
+
if isinstance(i, dict):
|
|
282
|
+
for k, v in i.items():
|
|
283
|
+
packmtd = getattr(self, '_pack_std_item_' + k, self._pack_void_item)
|
|
284
|
+
packed.append(packmtd(v))
|
|
285
|
+
else:
|
|
286
|
+
packed.append(self._pack_void_item(i))
|
|
287
|
+
return packed
|
|
288
|
+
|
|
289
|
+
def _pack_std_items_negativetimes(self, items):
|
|
290
|
+
return [(t[1:] + 'ago' if t[0] == '-' else t)
|
|
291
|
+
for t in self._pack_std_items(items)]
|
|
292
|
+
|
|
293
|
+
def _pack_std_items_datestuff(self, d, fatal=False):
|
|
294
|
+
"""Specialised version of _pack_std_items that deals with date/cutoff pairs."""
|
|
295
|
+
flowdate = None
|
|
296
|
+
flowcut = None
|
|
297
|
+
if isinstance(d, (tuple, list)):
|
|
298
|
+
for flowitem in [x for x in d if isinstance(x, dict)]:
|
|
299
|
+
if 'date' in flowitem:
|
|
300
|
+
flowdate = flowitem['date']
|
|
301
|
+
if 'shortcutoff' in flowitem:
|
|
302
|
+
flowcut = flowitem['shortcutoff']
|
|
303
|
+
if flowdate is None:
|
|
304
|
+
if fatal:
|
|
305
|
+
raise VortexNameBuilderError('A date is mandatory here...')
|
|
306
|
+
else:
|
|
307
|
+
return ''
|
|
308
|
+
return self._pack_std_item_date(flowdate) + self._pack_std_item_shortcutoff(flowcut)
|
|
309
|
+
|
|
310
|
+
def _pack_std_items_periodstuff(self, d, fatal=False):
|
|
311
|
+
"""Specialised version of _pack_std_items that deals with begindate/enddate/cutoff pairs."""
|
|
312
|
+
flowbegin = None
|
|
313
|
+
flowend = None
|
|
314
|
+
flowcut = None
|
|
315
|
+
if isinstance(d, (tuple, list)):
|
|
316
|
+
for flowitem in [x for x in d if isinstance(x, dict)]:
|
|
317
|
+
if 'begindate' in flowitem:
|
|
318
|
+
flowbegin = flowitem['begindate']
|
|
319
|
+
if 'enddate' in flowitem:
|
|
320
|
+
flowend = flowitem['enddate']
|
|
321
|
+
if 'shortcutoff' in flowitem:
|
|
322
|
+
flowcut = flowitem['shortcutoff']
|
|
323
|
+
if flowbegin is None or flowend is None:
|
|
324
|
+
if fatal:
|
|
325
|
+
raise VortexNameBuilderError('A begindate/enddate pair is mandatory here...')
|
|
326
|
+
else:
|
|
327
|
+
return ''
|
|
328
|
+
return '-'.join([self._pack_std_item_date(flowbegin) +
|
|
329
|
+
self._pack_std_item_shortcutoff(flowcut, default=''),
|
|
330
|
+
self._pack_std_item_date(flowend)])
|
|
331
|
+
|
|
332
|
+
# A Vortex basename may include the following bits
|
|
333
|
+
|
|
334
|
+
def _pack_std_basename_prefixstuff(self, d): # @UnusedVariable
|
|
335
|
+
"""Adds any info about date, cutoff ..."""
|
|
336
|
+
name0 = d['radical']
|
|
337
|
+
name0 += self._join_basename_bit(d, 'src', prefix='.', sep='-')
|
|
338
|
+
name0 += self._join_basename_bit(d, 'filtername', prefix='.', sep='-')
|
|
339
|
+
name0 += self._join_basename_bit(d, 'geo', prefix='.', sep='-')
|
|
340
|
+
name0 += self._join_basename_bit(d, 'compute', prefix='.', sep='-')
|
|
341
|
+
return name0
|
|
342
|
+
|
|
343
|
+
def _pack_std_basename_flowstuff(self, d): # @UnusedVariable
|
|
344
|
+
"""Adds any info about date, cutoff ..."""
|
|
345
|
+
return ''
|
|
346
|
+
|
|
347
|
+
def _pack_std_basename_timestuff(self, d): # @UnusedVariable
|
|
348
|
+
"""Adds any info about term, period, ..."""
|
|
349
|
+
name = ''
|
|
350
|
+
if d['term'] is not None:
|
|
351
|
+
name += self._join_basename_bit(d, 'term', prefix='+', sep='.',
|
|
352
|
+
packcb=self._pack_std_items_negativetimes)
|
|
353
|
+
else:
|
|
354
|
+
if d['period'] is not None:
|
|
355
|
+
name += self._join_basename_bit(d, 'period', prefix='+', sep='-',
|
|
356
|
+
packcb=self._pack_std_items_negativetimes)
|
|
357
|
+
elif d['cen_period'] is not None:
|
|
358
|
+
name += self._join_basename_bit(d, 'cen_period', prefix='_', sep='_',
|
|
359
|
+
packcb=self._pack_std_items_negativetimes)
|
|
360
|
+
return name
|
|
361
|
+
|
|
362
|
+
def _pack_std_basename_suffixstuff(self, d): # @UnusedVariable
|
|
363
|
+
"""Adds any info about date, cutoff ..."""
|
|
364
|
+
name1 = ''
|
|
365
|
+
name1 += self._join_basename_bit(d, 'number', prefix='.', sep='-')
|
|
366
|
+
name1 += self._join_basename_bit(d, 'fmt', prefix='.', sep='.')
|
|
367
|
+
name1 += self._join_basename_bit(d, 'suffix', prefix='.', sep='.')
|
|
368
|
+
return name1
|
|
369
|
+
|
|
370
|
+
def _join_basename_bit(self, d, entry, prefix='.', sep='-', packcb=None):
|
|
371
|
+
if d[entry] is not None:
|
|
372
|
+
if packcb is None:
|
|
373
|
+
return prefix + sep.join(self._pack_std_items(d[entry]))
|
|
374
|
+
else:
|
|
375
|
+
return prefix + sep.join(packcb(d[entry]))
|
|
376
|
+
else:
|
|
377
|
+
return ''
|
|
378
|
+
|
|
379
|
+
# Methods that generates basenames
|
|
380
|
+
|
|
381
|
+
def _pack_basename_std(self, d):
|
|
382
|
+
"""
|
|
383
|
+
Main entry point to convert a description into a file name
|
|
384
|
+
according to the so-called standard style.
|
|
385
|
+
"""
|
|
386
|
+
return (self._pack_std_basename_prefixstuff(d).lower() +
|
|
387
|
+
self._pack_std_basename_flowstuff(d) +
|
|
388
|
+
self._pack_std_basename_timestuff(d) +
|
|
389
|
+
self._pack_std_basename_suffixstuff(d).lower())
|
|
390
|
+
|
|
391
|
+
# Methods that generates pathnames
|
|
392
|
+
|
|
393
|
+
def _pack_pathname_std(self, d):
|
|
394
|
+
"""
|
|
395
|
+
Main entry point to convert a description into a path name
|
|
396
|
+
according to the so-called standard style.
|
|
397
|
+
"""
|
|
398
|
+
raise NotImplementedError('This is an abstract method !')
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
class VortexDateNameBuilder(AbstractActualVortexNameBuilder):
|
|
402
|
+
"""A Standard Vortex NameBuilder (with date and cutoff)."""
|
|
403
|
+
|
|
404
|
+
_footprint = dict(
|
|
405
|
+
info = 'A Standard Vortex NameBuilder (with date and cutoff)',
|
|
406
|
+
attr = dict(
|
|
407
|
+
name = dict(
|
|
408
|
+
values = ['date@std', ],
|
|
409
|
+
),
|
|
410
|
+
)
|
|
411
|
+
)
|
|
412
|
+
|
|
413
|
+
# A Vortex basename may include the following bits
|
|
414
|
+
|
|
415
|
+
def _pack_std_basename_flowstuff(self, d):
|
|
416
|
+
"""Adds any info about term and period, ..."""
|
|
417
|
+
name = ''
|
|
418
|
+
if d['flow'] is not None:
|
|
419
|
+
pstuff = self._pack_std_items_periodstuff(d['flow'])
|
|
420
|
+
if pstuff:
|
|
421
|
+
name += '.' + pstuff
|
|
422
|
+
return name
|
|
423
|
+
|
|
424
|
+
# Methods that generates basenames
|
|
425
|
+
|
|
426
|
+
def _pack_basename_obs(self, d):
|
|
427
|
+
"""
|
|
428
|
+
Main entry point to convert a description into a file name
|
|
429
|
+
according to the so-called observation style.
|
|
430
|
+
"""
|
|
431
|
+
obsfmt = d.get('nativefmt', d.get('fmt', None))
|
|
432
|
+
if obsfmt is None:
|
|
433
|
+
raise VortexNameBuilderError()
|
|
434
|
+
name = '.'.join([
|
|
435
|
+
obsfmt + '-' + d.get('layout', 'std'),
|
|
436
|
+
'void' if d['stage'] is None else d['stage'],
|
|
437
|
+
'all' if d['part'] is None else d['part'],
|
|
438
|
+
])
|
|
439
|
+
if d['suffix'] is not None:
|
|
440
|
+
name = name + '.' + d['suffix']
|
|
441
|
+
|
|
442
|
+
return name.lower()
|
|
443
|
+
|
|
444
|
+
def _pack_basename_obsmap(self, d):
|
|
445
|
+
"""
|
|
446
|
+
Main entry point to convert a description into a file name
|
|
447
|
+
according to the so-called observation-map style.
|
|
448
|
+
"""
|
|
449
|
+
name = '.'.join((
|
|
450
|
+
d['radical'],
|
|
451
|
+
'-'.join(self._pack_std_items(d['stage'])),
|
|
452
|
+
'txt' if d['fmt'] is None else d['fmt'],
|
|
453
|
+
))
|
|
454
|
+
return name.lower()
|
|
455
|
+
|
|
456
|
+
# Methods that generates pathnames
|
|
457
|
+
|
|
458
|
+
def _pack_pathname_std(self, d):
|
|
459
|
+
"""
|
|
460
|
+
Main entry point to convert a description into a path name
|
|
461
|
+
according to the so-called standard style.
|
|
462
|
+
"""
|
|
463
|
+
pathbits = self._pack_pathname_init(d)
|
|
464
|
+
self._pack_pathname_append_flowdate(pathbits, d)
|
|
465
|
+
self._pack_pathname_append_scenario(pathbits, d)
|
|
466
|
+
self._pack_pathname_append_member(pathbits, d)
|
|
467
|
+
self._pack_pathname_append_block(pathbits, d)
|
|
468
|
+
return pathbits
|
|
469
|
+
|
|
470
|
+
_pack_pathname_obs = _pack_pathname_std
|
|
471
|
+
_pack_pathname_obsmap = _pack_pathname_std
|
|
472
|
+
|
|
473
|
+
|
|
474
|
+
class VortexPeriodNameBuilder(AbstractActualVortexNameBuilder):
|
|
475
|
+
"""A Standard Vortex NameBuilder (with period and cutoff)."""
|
|
476
|
+
|
|
477
|
+
_footprint = dict(
|
|
478
|
+
info = 'A Standard Vortex NameBuilder (with period and cutoff)',
|
|
479
|
+
attr = dict(
|
|
480
|
+
name = dict(
|
|
481
|
+
values = ['period@std', ],
|
|
482
|
+
),
|
|
483
|
+
)
|
|
484
|
+
)
|
|
485
|
+
|
|
486
|
+
# A Vortex basename may include the following bits
|
|
487
|
+
|
|
488
|
+
def _pack_std_basename_flowstuff(self, d):
|
|
489
|
+
name = ''
|
|
490
|
+
if d['flow'] is not None:
|
|
491
|
+
dstuff = self._pack_std_items_datestuff(d['flow'])
|
|
492
|
+
if dstuff:
|
|
493
|
+
name += '.' + dstuff
|
|
494
|
+
return name
|
|
495
|
+
|
|
496
|
+
# Methods that generates pathnames
|
|
497
|
+
|
|
498
|
+
def _pack_pathname_std(self, d):
|
|
499
|
+
"""
|
|
500
|
+
Main entry point to convert a description into a file name
|
|
501
|
+
according to the so-called standard style.
|
|
502
|
+
"""
|
|
503
|
+
pathbits = self._pack_pathname_init(d)
|
|
504
|
+
self._pack_pathname_append_flowperiod(pathbits, d)
|
|
505
|
+
self._pack_pathname_append_scenario(pathbits, d)
|
|
506
|
+
self._pack_pathname_append_member(pathbits, d)
|
|
507
|
+
self._pack_pathname_append_block(pathbits, d)
|
|
508
|
+
return pathbits
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
class VortexFlatNameBuilder(AbstractActualVortexNameBuilder):
|
|
512
|
+
"""'A Standard Vortex NameBuilder (without date or period)."""
|
|
513
|
+
|
|
514
|
+
_footprint = dict(
|
|
515
|
+
info = 'A Standard Vortex NameBuilder (without date or period)',
|
|
516
|
+
attr = dict(
|
|
517
|
+
name = dict(
|
|
518
|
+
values = ['flat@std', ],
|
|
519
|
+
),
|
|
520
|
+
)
|
|
521
|
+
)
|
|
522
|
+
|
|
523
|
+
# A Vortex basename may include the following bits
|
|
524
|
+
|
|
525
|
+
def _pack_std_basename_flowstuff(self, d):
|
|
526
|
+
name = ''
|
|
527
|
+
if d['flow'] is not None:
|
|
528
|
+
dstuff = self._pack_std_items_datestuff(d['flow'])
|
|
529
|
+
if dstuff:
|
|
530
|
+
name += '.' + dstuff
|
|
531
|
+
pstuff = self._pack_std_items_periodstuff(d['flow'])
|
|
532
|
+
if pstuff:
|
|
533
|
+
name += '.' + pstuff
|
|
534
|
+
return name
|
|
535
|
+
|
|
536
|
+
# Methods that generates pathnames
|
|
537
|
+
|
|
538
|
+
def _pack_pathname_std(self, d):
|
|
539
|
+
"""
|
|
540
|
+
Main entry point to convert a description into a file name
|
|
541
|
+
according to the so-called standard style.
|
|
542
|
+
"""
|
|
543
|
+
pathbits = self._pack_pathname_init(d)
|
|
544
|
+
self._pack_pathname_append_scenario(pathbits, d)
|
|
545
|
+
self._pack_pathname_append_member(pathbits, d)
|
|
546
|
+
self._pack_pathname_append_block(pathbits, d)
|
|
547
|
+
return pathbits
|
|
548
|
+
|
|
549
|
+
|
|
550
|
+
class VortexNameBuilder(AbstractVortexNameBuilderProxy):
|
|
551
|
+
|
|
552
|
+
_explicit = False
|
|
553
|
+
_footprint = dict(
|
|
554
|
+
info = 'Standard Vortex NameBuilder Proxy',
|
|
555
|
+
attr = dict(
|
|
556
|
+
name = dict(
|
|
557
|
+
values = ['std', ],
|
|
558
|
+
optional = True,
|
|
559
|
+
default = 'std',
|
|
560
|
+
),
|
|
561
|
+
)
|
|
562
|
+
)
|
|
563
|
+
|
|
564
|
+
def _pick_actual_builder(self, d):
|
|
565
|
+
"""Given the input dictionary, returns the appropriate builder object."""
|
|
566
|
+
actual_builder_name = 'flat@std'
|
|
567
|
+
if 'flow' in d and isinstance(d['flow'], (tuple, list)):
|
|
568
|
+
flowkeys = set()
|
|
569
|
+
for item in [item for item in d['flow'] if isinstance(item, dict)]:
|
|
570
|
+
flowkeys.update(item.keys())
|
|
571
|
+
if 'date' in flowkeys:
|
|
572
|
+
actual_builder_name = 'date@std'
|
|
573
|
+
elif 'begindate' in flowkeys and 'enddate' in flowkeys:
|
|
574
|
+
actual_builder_name = 'period@std'
|
|
575
|
+
return self._get_builder(actual_builder_name)
|