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.
Files changed (146) hide show
  1. vortex/__init__.py +135 -0
  2. vortex/algo/__init__.py +12 -0
  3. vortex/algo/components.py +2136 -0
  4. vortex/algo/mpitools.py +1648 -0
  5. vortex/algo/mpitools_templates/envelope_wrapper_default.tpl +27 -0
  6. vortex/algo/mpitools_templates/envelope_wrapper_mpiauto.tpl +29 -0
  7. vortex/algo/mpitools_templates/wrapstd_wrapper_default.tpl +18 -0
  8. vortex/algo/serversynctools.py +170 -0
  9. vortex/config.py +115 -0
  10. vortex/data/__init__.py +13 -0
  11. vortex/data/abstractstores.py +1572 -0
  12. vortex/data/containers.py +780 -0
  13. vortex/data/contents.py +596 -0
  14. vortex/data/executables.py +284 -0
  15. vortex/data/flow.py +113 -0
  16. vortex/data/geometries.ini +2689 -0
  17. vortex/data/geometries.py +703 -0
  18. vortex/data/handlers.py +1021 -0
  19. vortex/data/outflow.py +67 -0
  20. vortex/data/providers.py +465 -0
  21. vortex/data/resources.py +201 -0
  22. vortex/data/stores.py +1271 -0
  23. vortex/gloves.py +282 -0
  24. vortex/layout/__init__.py +27 -0
  25. vortex/layout/appconf.py +109 -0
  26. vortex/layout/contexts.py +511 -0
  27. vortex/layout/dataflow.py +1069 -0
  28. vortex/layout/jobs.py +1276 -0
  29. vortex/layout/monitor.py +833 -0
  30. vortex/layout/nodes.py +1424 -0
  31. vortex/layout/subjobs.py +464 -0
  32. vortex/nwp/__init__.py +11 -0
  33. vortex/nwp/algo/__init__.py +12 -0
  34. vortex/nwp/algo/assim.py +483 -0
  35. vortex/nwp/algo/clim.py +920 -0
  36. vortex/nwp/algo/coupling.py +609 -0
  37. vortex/nwp/algo/eda.py +632 -0
  38. vortex/nwp/algo/eps.py +613 -0
  39. vortex/nwp/algo/forecasts.py +745 -0
  40. vortex/nwp/algo/fpserver.py +927 -0
  41. vortex/nwp/algo/ifsnaming.py +403 -0
  42. vortex/nwp/algo/ifsroot.py +311 -0
  43. vortex/nwp/algo/monitoring.py +202 -0
  44. vortex/nwp/algo/mpitools.py +554 -0
  45. vortex/nwp/algo/odbtools.py +974 -0
  46. vortex/nwp/algo/oopsroot.py +735 -0
  47. vortex/nwp/algo/oopstests.py +186 -0
  48. vortex/nwp/algo/request.py +579 -0
  49. vortex/nwp/algo/stdpost.py +1285 -0
  50. vortex/nwp/data/__init__.py +12 -0
  51. vortex/nwp/data/assim.py +392 -0
  52. vortex/nwp/data/boundaries.py +261 -0
  53. vortex/nwp/data/climfiles.py +539 -0
  54. vortex/nwp/data/configfiles.py +149 -0
  55. vortex/nwp/data/consts.py +929 -0
  56. vortex/nwp/data/ctpini.py +133 -0
  57. vortex/nwp/data/diagnostics.py +181 -0
  58. vortex/nwp/data/eda.py +148 -0
  59. vortex/nwp/data/eps.py +383 -0
  60. vortex/nwp/data/executables.py +1039 -0
  61. vortex/nwp/data/fields.py +96 -0
  62. vortex/nwp/data/gridfiles.py +308 -0
  63. vortex/nwp/data/logs.py +551 -0
  64. vortex/nwp/data/modelstates.py +334 -0
  65. vortex/nwp/data/monitoring.py +220 -0
  66. vortex/nwp/data/namelists.py +644 -0
  67. vortex/nwp/data/obs.py +748 -0
  68. vortex/nwp/data/oopsexec.py +72 -0
  69. vortex/nwp/data/providers.py +182 -0
  70. vortex/nwp/data/query.py +217 -0
  71. vortex/nwp/data/stores.py +147 -0
  72. vortex/nwp/data/surfex.py +338 -0
  73. vortex/nwp/syntax/__init__.py +9 -0
  74. vortex/nwp/syntax/stdattrs.py +375 -0
  75. vortex/nwp/tools/__init__.py +10 -0
  76. vortex/nwp/tools/addons.py +35 -0
  77. vortex/nwp/tools/agt.py +55 -0
  78. vortex/nwp/tools/bdap.py +48 -0
  79. vortex/nwp/tools/bdcp.py +38 -0
  80. vortex/nwp/tools/bdm.py +21 -0
  81. vortex/nwp/tools/bdmp.py +49 -0
  82. vortex/nwp/tools/conftools.py +1311 -0
  83. vortex/nwp/tools/drhook.py +62 -0
  84. vortex/nwp/tools/grib.py +268 -0
  85. vortex/nwp/tools/gribdiff.py +99 -0
  86. vortex/nwp/tools/ifstools.py +163 -0
  87. vortex/nwp/tools/igastuff.py +249 -0
  88. vortex/nwp/tools/mars.py +56 -0
  89. vortex/nwp/tools/odb.py +548 -0
  90. vortex/nwp/tools/partitioning.py +234 -0
  91. vortex/nwp/tools/satrad.py +56 -0
  92. vortex/nwp/util/__init__.py +6 -0
  93. vortex/nwp/util/async.py +184 -0
  94. vortex/nwp/util/beacon.py +40 -0
  95. vortex/nwp/util/diffpygram.py +359 -0
  96. vortex/nwp/util/ens.py +198 -0
  97. vortex/nwp/util/hooks.py +128 -0
  98. vortex/nwp/util/taskdeco.py +81 -0
  99. vortex/nwp/util/usepygram.py +591 -0
  100. vortex/nwp/util/usetnt.py +87 -0
  101. vortex/proxy.py +6 -0
  102. vortex/sessions.py +341 -0
  103. vortex/syntax/__init__.py +9 -0
  104. vortex/syntax/stdattrs.py +628 -0
  105. vortex/syntax/stddeco.py +176 -0
  106. vortex/toolbox.py +982 -0
  107. vortex/tools/__init__.py +11 -0
  108. vortex/tools/actions.py +457 -0
  109. vortex/tools/addons.py +297 -0
  110. vortex/tools/arm.py +76 -0
  111. vortex/tools/compression.py +322 -0
  112. vortex/tools/date.py +20 -0
  113. vortex/tools/ddhpack.py +10 -0
  114. vortex/tools/delayedactions.py +672 -0
  115. vortex/tools/env.py +513 -0
  116. vortex/tools/folder.py +663 -0
  117. vortex/tools/grib.py +559 -0
  118. vortex/tools/lfi.py +746 -0
  119. vortex/tools/listings.py +354 -0
  120. vortex/tools/names.py +575 -0
  121. vortex/tools/net.py +1790 -0
  122. vortex/tools/odb.py +10 -0
  123. vortex/tools/parallelism.py +336 -0
  124. vortex/tools/prestaging.py +186 -0
  125. vortex/tools/rawfiles.py +10 -0
  126. vortex/tools/schedulers.py +413 -0
  127. vortex/tools/services.py +871 -0
  128. vortex/tools/storage.py +1061 -0
  129. vortex/tools/surfex.py +61 -0
  130. vortex/tools/systems.py +3396 -0
  131. vortex/tools/targets.py +384 -0
  132. vortex/util/__init__.py +9 -0
  133. vortex/util/config.py +1071 -0
  134. vortex/util/empty.py +24 -0
  135. vortex/util/helpers.py +184 -0
  136. vortex/util/introspection.py +63 -0
  137. vortex/util/iosponge.py +76 -0
  138. vortex/util/roles.py +51 -0
  139. vortex/util/storefunctions.py +103 -0
  140. vortex/util/structs.py +26 -0
  141. vortex/util/worker.py +150 -0
  142. vortex_nwp-2.0.0b1.dist-info/LICENSE +517 -0
  143. vortex_nwp-2.0.0b1.dist-info/METADATA +50 -0
  144. vortex_nwp-2.0.0b1.dist-info/RECORD +146 -0
  145. vortex_nwp-2.0.0b1.dist-info/WHEEL +5 -0
  146. 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,10 @@
1
+ """
2
+ Standalone tools for NWP
3
+ """
4
+
5
+ # Recursive inclusion of packages with potential FootprintBase classes
6
+ from . import conftools
7
+ from . import ifstools
8
+
9
+ #: Automatic export of data subpackage
10
+ __all__ = []
@@ -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
+ )
@@ -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)
@@ -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)
@@ -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)
@@ -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
@@ -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)