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
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module provides some pre-defined attributes descriptions or combined sets
|
|
3
|
+
of attributes description that could be used in the footprint definition of any
|
|
4
|
+
class which follow the :class:`footprints.Footprint` syntax.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from bronx.stdtypes.date import Time
|
|
8
|
+
import footprints
|
|
9
|
+
|
|
10
|
+
#: Export a set of attributes :data:`a_run`, etc..
|
|
11
|
+
__all__ = []
|
|
12
|
+
|
|
13
|
+
#: Usual Footprint for a single member (in an algo Component)
|
|
14
|
+
a_algo_member = dict(
|
|
15
|
+
info=("The current member's number " +
|
|
16
|
+
"(may be omitted in deterministic configurations)."),
|
|
17
|
+
optional=True,
|
|
18
|
+
type=int
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
#: Usual Footprint of the ``outputid`` attribute.
|
|
22
|
+
algo_member = footprints.Footprint(attr=dict(member=a_algo_member))
|
|
23
|
+
|
|
24
|
+
#: Known OOPS testcomponent ``run``
|
|
25
|
+
known_oops_testcomponent_runs = ['ootestcomponent', 'testcomponent', 'testvar']
|
|
26
|
+
|
|
27
|
+
#: Usual definition of the ``run`` attribute for OOPS binaries.
|
|
28
|
+
a_oops_run = dict(
|
|
29
|
+
info="The OOPS run (== task).",
|
|
30
|
+
optional=False,
|
|
31
|
+
)
|
|
32
|
+
#: Usual Footprint of the ``run`` attribute for OOPS binaries.
|
|
33
|
+
oops_run = footprints.Footprint(info='OOPS kind of run', attr=dict(run=a_oops_run))
|
|
34
|
+
|
|
35
|
+
#: Usual definition of the ``test_type`` attribute.
|
|
36
|
+
a_oops_test_type = dict(
|
|
37
|
+
info='Sub-test or family of sub-tests to be ran.',
|
|
38
|
+
optional=False,
|
|
39
|
+
)
|
|
40
|
+
#: Usual Footprint of the ``test_type`` attribute.
|
|
41
|
+
oops_test_type = footprints.Footprint(info='OOPS type of test', attr=dict(test_type=a_oops_test_type))
|
|
42
|
+
|
|
43
|
+
#: Usual definition of the ``expected_target`` attribute.
|
|
44
|
+
an_oops_expected_target = dict(
|
|
45
|
+
info=('Expected target for the test success'),
|
|
46
|
+
type=footprints.FPDict,
|
|
47
|
+
optional=True,
|
|
48
|
+
default=None
|
|
49
|
+
)
|
|
50
|
+
#: Usual Footprint of the ``expected_target`` attribute.
|
|
51
|
+
oops_expected_target = footprints.Footprint(attr=dict(expected_target=an_oops_expected_target))
|
|
52
|
+
|
|
53
|
+
#: Usual Footprint of a combined lists of members and terms
|
|
54
|
+
oops_members_terms_lists = footprints.Footprint(
|
|
55
|
+
info="Abstract footprint for a members/terms list.",
|
|
56
|
+
attr=dict(
|
|
57
|
+
members=dict(
|
|
58
|
+
info='A list of members.',
|
|
59
|
+
type=footprints.FPList,
|
|
60
|
+
),
|
|
61
|
+
terms=dict(
|
|
62
|
+
info='A list of effective terms.',
|
|
63
|
+
type=footprints.FPList,
|
|
64
|
+
optional=True,
|
|
65
|
+
default=footprints.FPList([Time(0), ])
|
|
66
|
+
),
|
|
67
|
+
)
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
#: Usual definition of the ``outputid`` attribute
|
|
71
|
+
a_outputid = dict(
|
|
72
|
+
info="The identifier for the encoding of post-processed fields.",
|
|
73
|
+
optional=True,
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
#: Usual Footprint of the ``outputid`` attribute.
|
|
77
|
+
outputid = footprints.Footprint(attr=dict(outputid=a_outputid))
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def _apply_outputid(cls):
|
|
81
|
+
"""Decorator that tweak the class in order to add OUTPUTID on the namelist"""
|
|
82
|
+
orig_pnd = getattr(cls, 'prepare_namelist_delta', None)
|
|
83
|
+
if orig_pnd is None:
|
|
84
|
+
raise ImportError('_apply_outputid can not be applied on {!s}'.format(cls))
|
|
85
|
+
|
|
86
|
+
def prepare_namelist_delta(self, rh, namcontents, namlocal):
|
|
87
|
+
namw = orig_pnd(self, rh, namcontents, namlocal)
|
|
88
|
+
if self.outputid is not None and any(['OUTPUTID' in nam_b.macros()
|
|
89
|
+
for nam_b in namcontents.values()]):
|
|
90
|
+
self._set_nam_macro(namcontents, namlocal, 'OUTPUTID', self.outputid)
|
|
91
|
+
namw = True
|
|
92
|
+
return namw
|
|
93
|
+
|
|
94
|
+
cls.prepare_namelist_delta = prepare_namelist_delta
|
|
95
|
+
return cls
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
#: Decorated footprint for the ``outputid`` attribute
|
|
99
|
+
outputid_deco = footprints.DecorativeFootprint(outputid,
|
|
100
|
+
decorator=[_apply_outputid, ])
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def show():
|
|
104
|
+
"""Returns available items and their type."""
|
|
105
|
+
dmod = globals()
|
|
106
|
+
for stda in sorted(filter(lambda x: x.startswith('a_') or isinstance(dmod[x], footprints.Footprint),
|
|
107
|
+
dmod.keys())):
|
|
108
|
+
print('{} ( {} ) :\n {}\n'.format(stda, type(dmod[stda]).__name__, dmod[stda]))
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
"""
|
|
112
|
+
This module provides some pre-defined attributes descriptions or combined sets
|
|
113
|
+
of attributes description that could be used in the footprint definition of any
|
|
114
|
+
class which follow the :class:`footprints.Footprint` syntax.
|
|
115
|
+
"""
|
|
116
|
+
|
|
117
|
+
import re
|
|
118
|
+
from functools import total_ordering
|
|
119
|
+
|
|
120
|
+
import footprints
|
|
121
|
+
|
|
122
|
+
from vortex.syntax.stddeco import namebuilding_append
|
|
123
|
+
|
|
124
|
+
#: Export some new class for attributes in footprint objects, eg : GenvKey
|
|
125
|
+
__all__ = ['GenvKey', 'GenvDomain']
|
|
126
|
+
|
|
127
|
+
domain_remap = dict()
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def _lowerattr(matchobj):
|
|
131
|
+
"""Internal and technical function returning lower case value of the complete match item."""
|
|
132
|
+
return matchobj.group(0).lower()
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
class GenvKey(str):
|
|
136
|
+
"""
|
|
137
|
+
Attribute for a GEnv cycle name.
|
|
138
|
+
Implicit attributes inside brackets are translated to lower case.
|
|
139
|
+
See also :mod:`vortex_gco.tools.genv`.
|
|
140
|
+
"""
|
|
141
|
+
|
|
142
|
+
def __new__(cls, value):
|
|
143
|
+
"""Proxy to ``str.__new___`` with attributes inside brackets translated to lower case."""
|
|
144
|
+
return str.__new__(cls, re.sub(r'\[\w+\]', _lowerattr, value.upper()))
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
a_gvar = dict(info='The key that identifies the resource in the Genv database.',
|
|
148
|
+
type=GenvKey,
|
|
149
|
+
optional=True,
|
|
150
|
+
doc_visibility=footprints.doc.visibility.ADVANCED,
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
#: Usual definition of the ``genv`` attribute.
|
|
154
|
+
gvar = footprints.Footprint(info='A GENV access key',
|
|
155
|
+
attr=dict(gvar=a_gvar))
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
class GenvDomain(str):
|
|
159
|
+
"""
|
|
160
|
+
Remap plain area names to specific Genv short domain names.
|
|
161
|
+
See also :mod:`vortex_gco.tools.genv`.
|
|
162
|
+
"""
|
|
163
|
+
|
|
164
|
+
def __new__(cls, value):
|
|
165
|
+
"""Proxy to ``str.__new___`` with on the fly remapping of domain names to short values."""
|
|
166
|
+
return str.__new__(cls, domain_remap.get(value, value))
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
a_gdomain = dict(info="The resource's geographical domain name in the Genv database.",
|
|
170
|
+
type=GenvDomain,
|
|
171
|
+
optional=True,
|
|
172
|
+
default='[geometry::area]',
|
|
173
|
+
doc_visibility=footprints.doc.visibility.ADVANCED,)
|
|
174
|
+
|
|
175
|
+
#: Usual definition of the ``gdomain`` attribute.
|
|
176
|
+
gdomain = footprints.Footprint(info='A domain name in GCO convention',
|
|
177
|
+
attr=dict(gdomain=a_gdomain))
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
@total_ordering
|
|
181
|
+
class ArpIfsSimplifiedCycle:
|
|
182
|
+
"""
|
|
183
|
+
Type that holds a simplified representation of an ArpegeIFS cycle.
|
|
184
|
+
|
|
185
|
+
It provides basic comparison operators to determine if a given cycle is more recent or not
|
|
186
|
+
compared to another one.
|
|
187
|
+
|
|
188
|
+
It can be used in a footprint specification.
|
|
189
|
+
"""
|
|
190
|
+
_cy_re = re.compile(r'(?:u(?:env|get):)?(?:cy|al)(\d+)(?:t(\d{1,3}))?(?=_|@|\.|$)(?:.*?(?:[_-]op(\d{1,3})))?')
|
|
191
|
+
_hash_shift = 10000
|
|
192
|
+
|
|
193
|
+
def __init__(self, cyclestr):
|
|
194
|
+
cy_match = self._cy_re.match(cyclestr)
|
|
195
|
+
if cy_match:
|
|
196
|
+
self._number = int(cy_match.group(1))
|
|
197
|
+
self._toulouse = (int(cy_match.group(2)) + 1
|
|
198
|
+
if cy_match.group(2) is not None else 0)
|
|
199
|
+
self._op = (int(cy_match.group(3)) + 1
|
|
200
|
+
if cy_match.group(3) is not None else 0)
|
|
201
|
+
else:
|
|
202
|
+
raise ValueError('Malformed cycle: {}'.format(cyclestr))
|
|
203
|
+
|
|
204
|
+
def __hash__(self):
|
|
205
|
+
return (self._number * self._hash_shift + self._toulouse) * self._hash_shift + self._op
|
|
206
|
+
|
|
207
|
+
def __eq__(self, other):
|
|
208
|
+
if not isinstance(other, ArpIfsSimplifiedCycle):
|
|
209
|
+
try:
|
|
210
|
+
other = ArpIfsSimplifiedCycle(other)
|
|
211
|
+
except (ValueError, TypeError):
|
|
212
|
+
return False
|
|
213
|
+
return hash(self) == hash(other)
|
|
214
|
+
|
|
215
|
+
def __gt__(self, other):
|
|
216
|
+
if not isinstance(other, ArpIfsSimplifiedCycle):
|
|
217
|
+
other = ArpIfsSimplifiedCycle(other)
|
|
218
|
+
return hash(self) > hash(other)
|
|
219
|
+
|
|
220
|
+
def __str__(self):
|
|
221
|
+
return ('cy{:d}'.format(self._number) +
|
|
222
|
+
('t{:d}'.format(self._toulouse - 1) if self._toulouse else '') +
|
|
223
|
+
('_op{:d}'.format(self._op - 1) if self._op else ''))
|
|
224
|
+
|
|
225
|
+
def __repr__(self):
|
|
226
|
+
return '<{} | {!s}>'.format(object.__repr__(self).lstrip('<').rstrip('>'), self)
|
|
227
|
+
|
|
228
|
+
def export_dict(self):
|
|
229
|
+
"""The pure dict/json output is the raw integer"""
|
|
230
|
+
return str(self)
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
a_arpifs_cycle = dict(info="An Arpege/IFS cycle name",
|
|
234
|
+
type=ArpIfsSimplifiedCycle,
|
|
235
|
+
optional=True,
|
|
236
|
+
default='cy40', # For "old" Olive configurations to keep working
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
#: Usual definition of the ``cycle`` attribute.
|
|
240
|
+
arpifs_cycle = footprints.Footprint(info='An abstract arpifs_cycle in GCO convention',
|
|
241
|
+
attr=dict(cycle=a_arpifs_cycle))
|
|
242
|
+
|
|
243
|
+
uget_sloppy_id_regex = re.compile(r'(?P<shortuget>(?P<id>\S+)@(?P<location>[-\w]+))')
|
|
244
|
+
uget_id_regex = r'(?P<fulluget>u(?:get|env):' + uget_sloppy_id_regex.pattern + ')'
|
|
245
|
+
uget_id_regex_only = re.compile('^' + uget_id_regex + '$')
|
|
246
|
+
uget_id_regex = re.compile(r'\b' + uget_id_regex + r'\b')
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
class GgetId(str):
|
|
250
|
+
"""Basestring wrapper for Gget Ids."""
|
|
251
|
+
def __new__(cls, value):
|
|
252
|
+
if uget_id_regex_only.match(value):
|
|
253
|
+
raise ValueError('A GgetId cannot look like a UgetId !')
|
|
254
|
+
return str.__new__(cls, value)
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
class AbstractUgetId(str):
|
|
258
|
+
"""Basestring wrapper for Uget Ids."""
|
|
259
|
+
|
|
260
|
+
_ALLOWED_LOCATIONS = ()
|
|
261
|
+
_OUTCAST_LOCATIONS = ()
|
|
262
|
+
|
|
263
|
+
def __new__(cls, value):
|
|
264
|
+
vmatch = uget_id_regex_only.match(value)
|
|
265
|
+
if not vmatch:
|
|
266
|
+
raise ValueError('Invalid UgetId (got "{:s}")'.format(value))
|
|
267
|
+
me = str.__new__(cls, value)
|
|
268
|
+
me._id = vmatch.group('id')
|
|
269
|
+
me._location = vmatch.group('location')
|
|
270
|
+
if me._location in set(cls._OUTCAST_LOCATIONS):
|
|
271
|
+
raise ValueError('Invalid UgetId (got "{:s}"). Outcast Location.'.format(value))
|
|
272
|
+
if cls._ALLOWED_LOCATIONS and me._location not in set(cls._ALLOWED_LOCATIONS):
|
|
273
|
+
raise ValueError('Invalid UgetId (got "{:s}"). Disallowed location'.format(value))
|
|
274
|
+
return me
|
|
275
|
+
|
|
276
|
+
@property
|
|
277
|
+
def id(self):
|
|
278
|
+
return self._id
|
|
279
|
+
|
|
280
|
+
@property
|
|
281
|
+
def location(self):
|
|
282
|
+
return self._location
|
|
283
|
+
|
|
284
|
+
@property
|
|
285
|
+
def short(self):
|
|
286
|
+
return self._id + '@' + self._location
|
|
287
|
+
|
|
288
|
+
def monthlyshort(self, month):
|
|
289
|
+
return self._id + '.m{:02d}'.format(month) + '@' + self._location
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
class UgetId(AbstractUgetId):
|
|
293
|
+
|
|
294
|
+
_OUTCAST_LOCATIONS = ('demo', )
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
def genv_ifs_compiler_convention(cls):
|
|
298
|
+
"""Add the necessary method to handle compiler version/option in Genv."""
|
|
299
|
+
original_gget_basename = getattr(cls, 'gget_basename', None)
|
|
300
|
+
if original_gget_basename is not None:
|
|
301
|
+
|
|
302
|
+
def gget_basename(self):
|
|
303
|
+
"""GGET specific naming convention."""
|
|
304
|
+
b_dict = original_gget_basename(self)
|
|
305
|
+
if getattr(self, 'compiler_version', None):
|
|
306
|
+
b_dict['compiler_version'] = self.compiler_version
|
|
307
|
+
if getattr(self, 'compiler_option', None):
|
|
308
|
+
b_dict['compiler_option'] = self.compiler_option
|
|
309
|
+
if getattr(self, 'cycle', None):
|
|
310
|
+
b_dict['cycle'] = self.cycle
|
|
311
|
+
return b_dict
|
|
312
|
+
|
|
313
|
+
cls.gget_basename = gget_basename
|
|
314
|
+
return cls
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
#: Usual definition of the ``compiler_version`` and ``compiler_option`` attributes.
|
|
318
|
+
gmkpack_compiler_identification = footprints.Footprint(
|
|
319
|
+
info='Add the compiler version/option in the footprint',
|
|
320
|
+
attr=dict(
|
|
321
|
+
compiler_version=dict(
|
|
322
|
+
info="The compiler version in gmkpack convention.",
|
|
323
|
+
optional=True
|
|
324
|
+
),
|
|
325
|
+
compiler_option=dict(
|
|
326
|
+
info="The compiler option in gmkpack convention.",
|
|
327
|
+
optional=True
|
|
328
|
+
),
|
|
329
|
+
),
|
|
330
|
+
)
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
#: Usual definition of the ``compiler_version`` and ``compiler_option`` attributes + genv integration.
|
|
334
|
+
gmkpack_compiler_identification_deco = footprints.DecorativeFootprint(
|
|
335
|
+
gmkpack_compiler_identification,
|
|
336
|
+
decorator=[genv_ifs_compiler_convention, ]
|
|
337
|
+
)
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
def genv_executable_flavour(cls):
|
|
341
|
+
"""Add the necessary method to the "flavour" in Genv."""
|
|
342
|
+
original_genv_basename = getattr(cls, 'genv_basename', None)
|
|
343
|
+
if original_genv_basename is not None:
|
|
344
|
+
|
|
345
|
+
def genv_basename(self):
|
|
346
|
+
"""Just retrieve a potential gvar attribute."""
|
|
347
|
+
gvar = original_genv_basename(self)
|
|
348
|
+
if getattr(self, 'flavour', None):
|
|
349
|
+
gvar += '_' + {'singleprecision': 'SP'
|
|
350
|
+
}.get(self.flavour, self.flavour).upper()
|
|
351
|
+
return gvar
|
|
352
|
+
|
|
353
|
+
cls.genv_basename = genv_basename
|
|
354
|
+
return cls
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
#: Usual definition of the ``flavour`` attribute.
|
|
358
|
+
executable_flavour = footprints.Footprint(
|
|
359
|
+
info='Add the executable flavour attribute to the resource',
|
|
360
|
+
attr=dict(
|
|
361
|
+
flavour=dict(
|
|
362
|
+
info="The executable flavour (This may influence the Genv's key choice).",
|
|
363
|
+
values=['singleprecision', ],
|
|
364
|
+
optional=True,
|
|
365
|
+
),
|
|
366
|
+
),
|
|
367
|
+
)
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
#: Usual definition of the ``flavour``.
|
|
371
|
+
executable_flavour_deco = footprints.DecorativeFootprint(
|
|
372
|
+
executable_flavour,
|
|
373
|
+
decorator=[genv_executable_flavour,
|
|
374
|
+
namebuilding_append('src', lambda self: [self.flavour], none_discard=True)]
|
|
375
|
+
)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Various System needed for NWP applications.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from vortex.tools.addons import AddonGroup
|
|
6
|
+
|
|
7
|
+
# Load the proper Addon modules...
|
|
8
|
+
import vortex.tools.folder # @UnusedImport
|
|
9
|
+
import vortex.tools.lfi # @UnusedImport
|
|
10
|
+
import vortex.tools.grib # @UnusedImport
|
|
11
|
+
import vortex.tools.listings # @UnusedImport
|
|
12
|
+
import vortex.tools.surfex # @UnusedImport
|
|
13
|
+
|
|
14
|
+
#: No automatic export
|
|
15
|
+
__all__ = []
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class NWPAddonsGroup(AddonGroup):
|
|
19
|
+
"""A set of usual NWP Addons."""
|
|
20
|
+
|
|
21
|
+
_footprint = dict(
|
|
22
|
+
info = 'Default NWP Addons',
|
|
23
|
+
attr = dict(
|
|
24
|
+
kind = dict(
|
|
25
|
+
values = ['nwp', ],
|
|
26
|
+
),
|
|
27
|
+
)
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
_addonslist = ('allfolders', # Folder like...
|
|
31
|
+
'lfi', 'iopoll', # Wonderful FA/LFI world...
|
|
32
|
+
'grib', 'gribapi', # GRIB stuff...
|
|
33
|
+
'arpifs_listings', # Obscure IFS/Arpege listings...
|
|
34
|
+
'sfx', # Surfex...
|
|
35
|
+
)
|
vortex/nwp/tools/agt.py
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"""
|
|
2
|
+
TODO: Module documentation.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import collections
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class AgtConfigurationError(Exception):
|
|
9
|
+
"""Specific Transfer Agent configuration error."""
|
|
10
|
+
pass
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def agt_volatile_path(sh):
|
|
14
|
+
"""Prefix path to use for the Transfer Agent to consider a file as being "volatile"
|
|
15
|
+
and hard-linking to it instead of expecting it to be present "later".
|
|
16
|
+
"""
|
|
17
|
+
config = sh.default_target.config
|
|
18
|
+
if not config.has_section('agt'):
|
|
19
|
+
fmt = 'Missing section "agt" in configuration file\n"{}"'
|
|
20
|
+
raise AgtConfigurationError(fmt.format(config.file))
|
|
21
|
+
return config.get('agt', 'agt_volatile')
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def agt_actual_command(sh, binary_name, args, extraenv=None):
|
|
25
|
+
"""Build the command able to execute a Transfer Agent binary.
|
|
26
|
+
|
|
27
|
+
The context, the execution path and the command name are
|
|
28
|
+
provided by the configuration file of the target.
|
|
29
|
+
|
|
30
|
+
The resulting command should be executed on a transfer node.
|
|
31
|
+
|
|
32
|
+
:param sh: The vortex shell that will be used
|
|
33
|
+
:param binary_name: Key in the configuration file that holds the binary name
|
|
34
|
+
:param args: Argument to the AGT binary
|
|
35
|
+
:param extraenv: Additional environment variables to export (dictionary)
|
|
36
|
+
"""
|
|
37
|
+
config = sh.default_target.config
|
|
38
|
+
if not config.has_section('agt'):
|
|
39
|
+
fmt = 'Missing section "agt" in configuration file\n"{}"'
|
|
40
|
+
raise AgtConfigurationError(fmt.format(config.file))
|
|
41
|
+
|
|
42
|
+
agt_path = sh.default_target.get('agt_path', default=None)
|
|
43
|
+
agt_bin = sh.default_target.get(binary_name, default=None)
|
|
44
|
+
if not all([agt_path, agt_bin]):
|
|
45
|
+
fmt = 'Missing key "agt_path" or "{}" in configuration file\n"{}"'
|
|
46
|
+
raise AgtConfigurationError(fmt.format(binary_name, config.file))
|
|
47
|
+
cfgkeys = ['HOME_SOPRA', 'LD_LIBRARY_PATH',
|
|
48
|
+
'base_transfert_agent', 'DIAP_AGENT_NUMPROG_AGENT']
|
|
49
|
+
context = ' ; '.join(["export {}={}".format(key, config.get('agt', key))
|
|
50
|
+
for key in cfgkeys])
|
|
51
|
+
if extraenv is not None and isinstance(extraenv, collections.abc.Mapping):
|
|
52
|
+
context = ' ; '.join([context, ] +
|
|
53
|
+
["export {}={}".format(key.upper(), value)
|
|
54
|
+
for (key, value) in extraenv.items()])
|
|
55
|
+
return '{} ; {} {}'.format(context, sh.path.join(agt_path, agt_bin), args)
|
vortex/nwp/tools/bdap.py
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Utility classes and function to work with the BDAP database.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
#: No automatic export
|
|
6
|
+
__all__ = []
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class BDAPError(Exception):
|
|
10
|
+
"""General BDAP error."""
|
|
11
|
+
pass
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class BDAPRequestConfigurationError(BDAPError):
|
|
15
|
+
"""Specific Transfer Agent configuration error."""
|
|
16
|
+
pass
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class BDAPGetError(BDAPError):
|
|
20
|
+
"""Generic BDAP get error."""
|
|
21
|
+
pass
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def BDAPrequest_actual_command(command, date, term, query, int_extraenv=False):
|
|
25
|
+
"""Build the command able to execute a BDAP request.
|
|
26
|
+
|
|
27
|
+
The context, the execution path and the command name are
|
|
28
|
+
provided by the configuration file of the target.
|
|
29
|
+
|
|
30
|
+
The resulting command should be executed on a transfer node.
|
|
31
|
+
|
|
32
|
+
:param command: name of the BDAP request command to be used
|
|
33
|
+
:param date: the date of the file requested
|
|
34
|
+
:param term: the term of the file requested
|
|
35
|
+
:param query: the query file used for the request
|
|
36
|
+
:param int_extraenv: boolean to know if the integration BDAP is used or not
|
|
37
|
+
(an additional environment variable has to be exported in this case).
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
# Environment variable to specify the date of the file
|
|
41
|
+
context = ' ; '.join(["export {}={}".format('dmt_date_pivot'.upper(), date.ymdhms)])
|
|
42
|
+
# Extra environment variables (integration BDAP)
|
|
43
|
+
if int_extraenv:
|
|
44
|
+
context = ' ; '.join([context] +
|
|
45
|
+
["export {}={}".format('db_file_bdap'.upper(),
|
|
46
|
+
'/usr/local/sopra/neons_db_bdap.intgr')])
|
|
47
|
+
# Return the command to be launched
|
|
48
|
+
return '{} ; {} {:d} {}'.format(context, command, term.hour, query)
|
vortex/nwp/tools/bdcp.py
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Utility classes and function to work with the BDCP database.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
#: No automatic export
|
|
6
|
+
__all__ = []
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class BDCPError(Exception):
|
|
10
|
+
"""General BDMP error."""
|
|
11
|
+
pass
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class BDCPRequestConfigurationError(BDCPError):
|
|
15
|
+
"""Specific Transfer Agent configuration error."""
|
|
16
|
+
pass
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class BDCPGetError(BDCPError):
|
|
20
|
+
"""Generic BDCP get error."""
|
|
21
|
+
pass
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def BDCPrequest_actual_command(command, query_file, output_file):
|
|
25
|
+
"""Build the command able to execute a BDCP request.
|
|
26
|
+
|
|
27
|
+
The context, the execution path and the command name are
|
|
28
|
+
provided by the configuration file of the target.
|
|
29
|
+
|
|
30
|
+
The resulting command should be executed on a transfer node.
|
|
31
|
+
|
|
32
|
+
:param command: name of the BDMP request command to be used
|
|
33
|
+
:param query_file: the query file used for the request
|
|
34
|
+
:param output_file: the file in which the result will be written
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
# Return the command to be launched
|
|
38
|
+
return '{} -D {} -f {}'.format(command, query_file, output_file)
|
vortex/nwp/tools/bdm.py
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Utility classes and function to work with the BDM database.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
#: No automatic export
|
|
6
|
+
__all__ = []
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class BDMError(Exception):
|
|
10
|
+
"""General BDM error."""
|
|
11
|
+
pass
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class BDMRequestConfigurationError(BDMError):
|
|
15
|
+
"""Specific Transfer Agent configuration error."""
|
|
16
|
+
pass
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class BDMGetError(BDMError):
|
|
20
|
+
"""Generic BDM get error."""
|
|
21
|
+
pass
|
vortex/nwp/tools/bdmp.py
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Utility classes and function to work with the BDMP database.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
#: No automatic export
|
|
6
|
+
__all__ = []
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class BDMPError(Exception):
|
|
10
|
+
"""General BDMP error."""
|
|
11
|
+
pass
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class BDMPRequestConfigurationError(BDMPError):
|
|
15
|
+
"""Specific Transfer Agent configuration error."""
|
|
16
|
+
pass
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class BDMPGetError(BDMPError):
|
|
20
|
+
"""Generic BDMP get error."""
|
|
21
|
+
pass
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def BDMPrequest_actual_command(command, query, target_bdmp):
|
|
25
|
+
"""Build the command able to execute a BDMP request.
|
|
26
|
+
|
|
27
|
+
The context, the execution path and the command name are
|
|
28
|
+
provided by the configuration file of the target.
|
|
29
|
+
|
|
30
|
+
The resulting command should be executed on a transfer node.
|
|
31
|
+
|
|
32
|
+
:param command: name of the BDMP request command to be used
|
|
33
|
+
:param query: the query file used for the request
|
|
34
|
+
:param target_bdmp: string to determine the BDMP used
|
|
35
|
+
"""
|
|
36
|
+
# Environment variable used for the request
|
|
37
|
+
extraenv_pwd = "export {} {}".format('pwd_file'.upper(), '/usr/local/sopra/neons_pwd')
|
|
38
|
+
if target_bdmp == 'OPER':
|
|
39
|
+
extraenv_db = '/usr/local/sopra/neons_db_bdm'
|
|
40
|
+
elif target_bdmp == 'INTE':
|
|
41
|
+
extraenv_db = '/usr/local/sopra/neons_db_bdm.archi'
|
|
42
|
+
elif target_bdmp == 'ARCH':
|
|
43
|
+
extraenv_db = '/usr/local/sopra/neons_db_bdm.intgr'
|
|
44
|
+
else:
|
|
45
|
+
raise BDMPError
|
|
46
|
+
extraenv_db = 'export {} {}'.format('db_file_bdm'.upper(), extraenv_db)
|
|
47
|
+
|
|
48
|
+
# Return the command to be launched
|
|
49
|
+
return '{} ; {} ; {} {}'.format(extraenv_pwd, extraenv_db, command, query)
|