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,12 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Data resources (mostly NWP).
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
# Recursive inclusion of packages with potential FootprintBase classes
|
|
6
|
+
from . import boundaries, climfiles, consts, diagnostics, executables, fields
|
|
7
|
+
from . import assim, gridfiles, logs, modelstates, namelists, obs, surfex, eps, eda
|
|
8
|
+
from . import providers, stores, query, monitoring, ctpini
|
|
9
|
+
from . import oopsexec, configfiles
|
|
10
|
+
|
|
11
|
+
#: No automatic export
|
|
12
|
+
__all__ = []
|
vortex/nwp/data/assim.py
ADDED
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Various resources needed to build ad Data Assimilmation system.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from bronx.fancies import loggers
|
|
6
|
+
from bronx.stdtypes.date import Time
|
|
7
|
+
|
|
8
|
+
from vortex.data.flow import FlowResource, GeoFlowResource
|
|
9
|
+
from vortex.data.contents import JsonDictContent
|
|
10
|
+
from vortex.data.executables import Script
|
|
11
|
+
from vortex.syntax.stddeco import namebuilding_append, namebuilding_insert
|
|
12
|
+
from vortex.syntax.stdattrs import FmtInt, term_deco
|
|
13
|
+
from ..syntax.stdattrs import gvar
|
|
14
|
+
|
|
15
|
+
#: Automatic export off
|
|
16
|
+
__all__ = []
|
|
17
|
+
|
|
18
|
+
logger = loggers.getLogger(__name__)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@namebuilding_insert('geo', lambda s: s._geo2basename_info(add_stretching=False))
|
|
22
|
+
class _BackgroundErrorInfo(GeoFlowResource):
|
|
23
|
+
"""
|
|
24
|
+
A generic class for data in grib format related to the background error.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
_abstract = True
|
|
28
|
+
_footprint = [
|
|
29
|
+
term_deco,
|
|
30
|
+
gvar,
|
|
31
|
+
dict(
|
|
32
|
+
info='Background standard deviation',
|
|
33
|
+
attr=dict(
|
|
34
|
+
term=dict(
|
|
35
|
+
optional=True,
|
|
36
|
+
default=3
|
|
37
|
+
),
|
|
38
|
+
nativefmt=dict(
|
|
39
|
+
default='grib',
|
|
40
|
+
),
|
|
41
|
+
gvar = dict(
|
|
42
|
+
default = 'errgrib_t[geometry:truncation]'
|
|
43
|
+
),
|
|
44
|
+
),
|
|
45
|
+
)
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
def realkind(self):
|
|
50
|
+
return 'bgstdinfo'
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class BackgroundStdError(_BackgroundErrorInfo):
|
|
54
|
+
"""Background error standard deviation.
|
|
55
|
+
|
|
56
|
+
stage:
|
|
57
|
+
* unbal/vor: unbalanced variables fields
|
|
58
|
+
* scr: obs. related fields
|
|
59
|
+
* profile: full variables global and latitude bands horizontal averages
|
|
60
|
+
* full: full variables fields
|
|
61
|
+
|
|
62
|
+
origin:
|
|
63
|
+
* ens: diagnosed from an ensemble
|
|
64
|
+
* diag: diagnosed from randomized (a priori climatological) covariances
|
|
65
|
+
|
|
66
|
+
"""
|
|
67
|
+
|
|
68
|
+
_footprint = dict(
|
|
69
|
+
info='Background error standard deviation',
|
|
70
|
+
attr=dict(
|
|
71
|
+
kind=dict(
|
|
72
|
+
values=['bgstderr', 'bg_stderr', 'bgerrstd'],
|
|
73
|
+
remap=dict(autoremap='first'),
|
|
74
|
+
),
|
|
75
|
+
stage=dict(
|
|
76
|
+
optional=True,
|
|
77
|
+
default='unbal',
|
|
78
|
+
values=['scr', 'vor', 'full', 'unbal', 'profile'],
|
|
79
|
+
remap=dict(vor='unbal'),
|
|
80
|
+
),
|
|
81
|
+
origin=dict(
|
|
82
|
+
optional=True,
|
|
83
|
+
values=['ens', 'diag'],
|
|
84
|
+
default = 'ens',
|
|
85
|
+
),
|
|
86
|
+
gvar = dict(
|
|
87
|
+
default = 'errgrib_vor_monthly'
|
|
88
|
+
),
|
|
89
|
+
nativefmt=dict(
|
|
90
|
+
values=['grib', 'ascii'],
|
|
91
|
+
default='grib',
|
|
92
|
+
),
|
|
93
|
+
),
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
@property
|
|
97
|
+
def realkind(self):
|
|
98
|
+
return 'bgstderr'
|
|
99
|
+
|
|
100
|
+
def namebuilding_info(self):
|
|
101
|
+
"""Generic information for names fabric, with radical = ``bcor``."""
|
|
102
|
+
infos = super().namebuilding_info()
|
|
103
|
+
infos['src'].append(self.stage)
|
|
104
|
+
if self.stage != 'scr':
|
|
105
|
+
infos['src'].append(self.origin)
|
|
106
|
+
return infos
|
|
107
|
+
|
|
108
|
+
def archive_basename(self):
|
|
109
|
+
"""OP ARCHIVE specific naming convention."""
|
|
110
|
+
if self.stage in ('unbal',):
|
|
111
|
+
return '(errgribfix:igakey)'
|
|
112
|
+
else:
|
|
113
|
+
return 'errgrib_' + self.stage
|
|
114
|
+
|
|
115
|
+
def olive_basename(self):
|
|
116
|
+
"""OLIVE specific naming convention."""
|
|
117
|
+
if self.stage in ('unbal',):
|
|
118
|
+
return 'errgribvor'
|
|
119
|
+
else:
|
|
120
|
+
return 'sigma_b'
|
|
121
|
+
|
|
122
|
+
def gget_basename(self):
|
|
123
|
+
"""GGET specific naming convention."""
|
|
124
|
+
return dict(suffix='.m{:02d}'.format(self.date.month))
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
@namebuilding_append('src', lambda s: s.variable)
|
|
128
|
+
class SplitBackgroundStdError(BackgroundStdError):
|
|
129
|
+
"""Background error standard deviation, for a given variable."""
|
|
130
|
+
|
|
131
|
+
_footprint = dict(
|
|
132
|
+
info='Background error standard deviation',
|
|
133
|
+
attr=dict(
|
|
134
|
+
variable=dict(
|
|
135
|
+
info = "Variable contained in this resource.",
|
|
136
|
+
),
|
|
137
|
+
gvar = dict(
|
|
138
|
+
default = 'errgrib_vor_[variable]_monthly'
|
|
139
|
+
),
|
|
140
|
+
),
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
class BackgroundErrorNorm(_BackgroundErrorInfo):
|
|
145
|
+
"""Background error normalisation data for wavelet covariances."""
|
|
146
|
+
|
|
147
|
+
_footprint = [
|
|
148
|
+
dict(
|
|
149
|
+
info='Background error normalisation data for wavelet covariances',
|
|
150
|
+
attr=dict(
|
|
151
|
+
kind=dict(
|
|
152
|
+
values=['bgstdrenorm', 'bgerrnorm'],
|
|
153
|
+
remap=dict(autoremap='first'),
|
|
154
|
+
),
|
|
155
|
+
gvar = dict(
|
|
156
|
+
default = 'srenorm_t[geometry:truncation]'
|
|
157
|
+
),
|
|
158
|
+
),
|
|
159
|
+
)
|
|
160
|
+
]
|
|
161
|
+
|
|
162
|
+
@property
|
|
163
|
+
def realkind(self):
|
|
164
|
+
return 'bgstdrenorm'
|
|
165
|
+
|
|
166
|
+
def archive_basename(self):
|
|
167
|
+
"""OP ARCHIVE specific naming convention."""
|
|
168
|
+
return 'srenorm.{!s}'.format(self.geometry.truncation)
|
|
169
|
+
|
|
170
|
+
def olive_basename(self):
|
|
171
|
+
"""OLIVE specific naming convention."""
|
|
172
|
+
return 'srenorm.t{!s}'.format(self.geometry.truncation)
|
|
173
|
+
|
|
174
|
+
def archive_pathinfo(self):
|
|
175
|
+
"""Op Archive specific pathname needs."""
|
|
176
|
+
return dict(
|
|
177
|
+
nativefmt=self.nativefmt,
|
|
178
|
+
model=self.model,
|
|
179
|
+
date=self.date,
|
|
180
|
+
cutoff=self.cutoff,
|
|
181
|
+
arpege_aearp_directory='wavelet',
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
@namebuilding_insert('geo', lambda s: s._geo2basename_info(add_stretching=False))
|
|
186
|
+
class Wavelet(GeoFlowResource):
|
|
187
|
+
"""Background error wavelet covariances."""
|
|
188
|
+
|
|
189
|
+
_footprint = [
|
|
190
|
+
term_deco,
|
|
191
|
+
gvar,
|
|
192
|
+
dict(
|
|
193
|
+
info = 'Background error wavelet covariances',
|
|
194
|
+
attr = dict(
|
|
195
|
+
kind = dict(
|
|
196
|
+
values = ['wavelet', 'waveletcv'],
|
|
197
|
+
remap = dict(autoremap = 'first'),
|
|
198
|
+
),
|
|
199
|
+
gvar = dict(
|
|
200
|
+
default = 'wavelet_cv_t[geometry:truncation]'
|
|
201
|
+
),
|
|
202
|
+
term=dict(
|
|
203
|
+
optional=True,
|
|
204
|
+
default=3
|
|
205
|
+
),
|
|
206
|
+
)
|
|
207
|
+
)
|
|
208
|
+
]
|
|
209
|
+
|
|
210
|
+
@property
|
|
211
|
+
def realkind(self):
|
|
212
|
+
return 'wavelet'
|
|
213
|
+
|
|
214
|
+
def archive_basename(self):
|
|
215
|
+
"""OP ARCHIVE specific naming convention."""
|
|
216
|
+
return 'wavelet.cv.{!s}'.format(self.geometry.truncation)
|
|
217
|
+
|
|
218
|
+
def olive_basename(self):
|
|
219
|
+
"""OLIVE specific naming convention."""
|
|
220
|
+
return 'wavelet.cv.t{!s}'.format(self.geometry.truncation)
|
|
221
|
+
|
|
222
|
+
def archive_pathinfo(self):
|
|
223
|
+
"""Op Archive specific pathname needs."""
|
|
224
|
+
return dict(
|
|
225
|
+
nativefmt=self.nativefmt,
|
|
226
|
+
model=self.model,
|
|
227
|
+
date=self.date,
|
|
228
|
+
cutoff=self.cutoff,
|
|
229
|
+
arpege_aearp_directory=self.realkind,
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
@namebuilding_insert('geo', lambda s: s._geo2basename_info(add_stretching=False))
|
|
234
|
+
class RawControlVector(GeoFlowResource):
|
|
235
|
+
"""Raw Control Vector as issued by minimisation, playing the role of an Increment."""
|
|
236
|
+
|
|
237
|
+
_footprint = dict(
|
|
238
|
+
info = 'Raw Control Vector',
|
|
239
|
+
attr = dict(
|
|
240
|
+
kind = dict(
|
|
241
|
+
values = ['rawcv', 'rcv', 'increment', 'minimcv'],
|
|
242
|
+
remap = dict(autoremap = 'first'),
|
|
243
|
+
),
|
|
244
|
+
)
|
|
245
|
+
)
|
|
246
|
+
|
|
247
|
+
@property
|
|
248
|
+
def realkind(self):
|
|
249
|
+
return 'rawcv'
|
|
250
|
+
|
|
251
|
+
def olive_basename(self):
|
|
252
|
+
"""OLIVE specific naming convention."""
|
|
253
|
+
return 'MININCR'
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
@namebuilding_insert('geo', lambda s: s._geo2basename_info(add_stretching=False))
|
|
257
|
+
class InternalMinim(GeoFlowResource):
|
|
258
|
+
"""Generic class for resources internal to minimisation."""
|
|
259
|
+
|
|
260
|
+
_abstract = True
|
|
261
|
+
_footprint = dict(
|
|
262
|
+
attr = dict(
|
|
263
|
+
nativefmt = dict(
|
|
264
|
+
values = ['fa', 'lfi', 'grib'],
|
|
265
|
+
default = 'fa',
|
|
266
|
+
),
|
|
267
|
+
term = dict(
|
|
268
|
+
type = Time,
|
|
269
|
+
optional = True,
|
|
270
|
+
default = Time(-3),
|
|
271
|
+
),
|
|
272
|
+
)
|
|
273
|
+
)
|
|
274
|
+
|
|
275
|
+
def olive_suffixtr(self):
|
|
276
|
+
"""Return BR or HR specific OLIVE suffix according to geo streching."""
|
|
277
|
+
return 'HR' if self.geometry.stretching > 1 else 'BR'
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
class StartingPointMinim(InternalMinim):
|
|
281
|
+
"""Guess as reprocessed by the minimisation."""
|
|
282
|
+
|
|
283
|
+
_footprint = dict(
|
|
284
|
+
info = 'Starting Point Output Minim',
|
|
285
|
+
attr = dict(
|
|
286
|
+
kind = dict(
|
|
287
|
+
values = ['stpmin'],
|
|
288
|
+
),
|
|
289
|
+
)
|
|
290
|
+
)
|
|
291
|
+
|
|
292
|
+
@property
|
|
293
|
+
def realkind(self):
|
|
294
|
+
return 'stpmin'
|
|
295
|
+
|
|
296
|
+
def olive_basename(self):
|
|
297
|
+
"""OLIVE specific naming convention."""
|
|
298
|
+
return 'STPMIN' + self.olive_suffixtr()
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
class AnalysedStateMinim(InternalMinim):
|
|
302
|
+
"""Analysed state as produced by the minimisation."""
|
|
303
|
+
|
|
304
|
+
_footprint = dict(
|
|
305
|
+
info = 'Analysed Output Minim',
|
|
306
|
+
attr = dict(
|
|
307
|
+
kind = dict(
|
|
308
|
+
values = ['anamin'],
|
|
309
|
+
),
|
|
310
|
+
)
|
|
311
|
+
)
|
|
312
|
+
|
|
313
|
+
@property
|
|
314
|
+
def realkind(self):
|
|
315
|
+
return 'anamin'
|
|
316
|
+
|
|
317
|
+
def olive_basename(self):
|
|
318
|
+
"""OLIVE specific naming convention."""
|
|
319
|
+
return 'ANAMIN' + self.olive_suffixtr()
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
class PrecevMap(FlowResource):
|
|
323
|
+
"""Map of the precondionning eigenvectors as produced by minimisation."""
|
|
324
|
+
|
|
325
|
+
_footprint = dict(
|
|
326
|
+
info = 'Prec EV Map',
|
|
327
|
+
attr = dict(
|
|
328
|
+
kind = dict(
|
|
329
|
+
values = ['precevmap'],
|
|
330
|
+
),
|
|
331
|
+
clscontents = dict(
|
|
332
|
+
default = JsonDictContent,
|
|
333
|
+
),
|
|
334
|
+
nativefmt = dict(
|
|
335
|
+
values = ['json'],
|
|
336
|
+
default = 'json',
|
|
337
|
+
),
|
|
338
|
+
)
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
@property
|
|
342
|
+
def realkind(self):
|
|
343
|
+
return 'precevmap'
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
@namebuilding_append('src', lambda s: str(s.evnum))
|
|
347
|
+
class Precev(FlowResource):
|
|
348
|
+
"""Precondionning eigenvectors as produced by minimisation."""
|
|
349
|
+
|
|
350
|
+
_footprint = dict(
|
|
351
|
+
info = 'Starting Point Output Minim',
|
|
352
|
+
attr = dict(
|
|
353
|
+
kind = dict(
|
|
354
|
+
values = ['precev'],
|
|
355
|
+
),
|
|
356
|
+
evnum = dict(
|
|
357
|
+
type = FmtInt,
|
|
358
|
+
args = dict(fmt = '03'),
|
|
359
|
+
),
|
|
360
|
+
)
|
|
361
|
+
)
|
|
362
|
+
|
|
363
|
+
@property
|
|
364
|
+
def realkind(self):
|
|
365
|
+
return 'precev'
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
class IOassignScript(Script):
|
|
369
|
+
"""Scripts for IOASSIGN."""
|
|
370
|
+
|
|
371
|
+
_footprint = [
|
|
372
|
+
gvar,
|
|
373
|
+
dict(
|
|
374
|
+
info = 'Script for IOASSIGN',
|
|
375
|
+
attr = dict(
|
|
376
|
+
kind = dict(
|
|
377
|
+
values = ['ioassign_script']
|
|
378
|
+
),
|
|
379
|
+
gvar = dict(
|
|
380
|
+
default = 'ioassign_script_[purpose]'
|
|
381
|
+
),
|
|
382
|
+
purpose=dict(
|
|
383
|
+
info = "The purpose of the script",
|
|
384
|
+
values = ['merge', 'create']
|
|
385
|
+
),
|
|
386
|
+
)
|
|
387
|
+
)
|
|
388
|
+
]
|
|
389
|
+
|
|
390
|
+
@property
|
|
391
|
+
def realkind(self):
|
|
392
|
+
return 'ioassign_script'
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Resources to handle any boundary conditions data for a coupled model.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import re
|
|
6
|
+
|
|
7
|
+
from bronx.stdtypes import date
|
|
8
|
+
import footprints
|
|
9
|
+
from vortex.tools import env
|
|
10
|
+
from vortex.data.flow import GeoFlowResource, GeoPeriodFlowResource
|
|
11
|
+
from vortex.syntax.stddeco import namebuilding_append, namebuilding_insert, overwrite_realkind
|
|
12
|
+
from vortex.syntax.stdattrs import term_deco, timeperiod_deco, a_cutoff
|
|
13
|
+
from vortex.data.geometries import LonlatGeometry
|
|
14
|
+
|
|
15
|
+
from ..tools.igastuff import archive_suffix
|
|
16
|
+
|
|
17
|
+
#: No automatic export
|
|
18
|
+
__all__ = []
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@namebuilding_insert('radical', lambda s: 'cpl')
|
|
22
|
+
@namebuilding_insert('src', lambda s: s._mysrc)
|
|
23
|
+
class _AbstractLAMBoundary(GeoFlowResource):
|
|
24
|
+
"""
|
|
25
|
+
Class of a coupling file for a Limited Area Model.
|
|
26
|
+
A SpectralGeometry object is needed.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
_abstract = True
|
|
30
|
+
_footprint = [
|
|
31
|
+
term_deco,
|
|
32
|
+
dict(
|
|
33
|
+
info = 'Coupling file for a limited area model',
|
|
34
|
+
attr = dict(
|
|
35
|
+
kind = dict(
|
|
36
|
+
values = ['boundary', 'elscf', 'coupled'],
|
|
37
|
+
remap = dict(autoremap = 'first'),
|
|
38
|
+
),
|
|
39
|
+
nativefmt = dict(
|
|
40
|
+
values = ['fa', 'grib', 'netcdf', 'ascii', 'wbcpack', 'unknown'],
|
|
41
|
+
default = 'fa',
|
|
42
|
+
),
|
|
43
|
+
)
|
|
44
|
+
)
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
@property
|
|
48
|
+
def realkind(self):
|
|
49
|
+
return 'boundary'
|
|
50
|
+
|
|
51
|
+
@property
|
|
52
|
+
def _mysrc(self):
|
|
53
|
+
raise NotImplementedError
|
|
54
|
+
|
|
55
|
+
def olive_basename(self):
|
|
56
|
+
"""OLIVE specific naming convention."""
|
|
57
|
+
if self.mailbox.get('block', '-') == 'surfan':
|
|
58
|
+
hhreal = self.term
|
|
59
|
+
else:
|
|
60
|
+
e = env.current()
|
|
61
|
+
if 'HHDELTA_CPL' in e:
|
|
62
|
+
actualbase = self.date - date.Time(e.HHDELTA_CPL + 'H')
|
|
63
|
+
else:
|
|
64
|
+
actualbase = date.synop(base=self.date)
|
|
65
|
+
hhreal = (self.date - actualbase).time() + self.term
|
|
66
|
+
return 'ELSCFALAD_' + self.geometry.area + '+' + hhreal.fmthour
|
|
67
|
+
|
|
68
|
+
def archive_basename(self):
|
|
69
|
+
"""OP ARCHIVE specific naming convention."""
|
|
70
|
+
suffix = archive_suffix(self.model, self.cutoff, self.date)
|
|
71
|
+
prefix = 'COUPL'
|
|
72
|
+
source = self._mysrc[0] if isinstance(self._mysrc, list) else self._mysrc
|
|
73
|
+
if re.match('assist1bis|testms1', self.geometry.area):
|
|
74
|
+
prefix = 'COUPL1'
|
|
75
|
+
if re.match('ifs|ecmwf', source) and '16km' in self.geometry.rnice:
|
|
76
|
+
prefix = 'COUPLIFS'
|
|
77
|
+
|
|
78
|
+
if self.model == 'mocage':
|
|
79
|
+
valid = (self.date + self.term).ymd
|
|
80
|
+
return 'SM' + self.geometry.area + '+' + valid
|
|
81
|
+
|
|
82
|
+
return prefix + self.term.fmthour + '.r{!s}'.format(suffix)
|
|
83
|
+
|
|
84
|
+
def iga_pathinfo(self):
|
|
85
|
+
"""Standard path information for IGA inline cache."""
|
|
86
|
+
if self.model == 'arome':
|
|
87
|
+
directory = 'fic_day'
|
|
88
|
+
elif self.model == 'mfwam':
|
|
89
|
+
directory = 'guess'
|
|
90
|
+
else:
|
|
91
|
+
directory = 'autres'
|
|
92
|
+
return dict(
|
|
93
|
+
fmt=directory,
|
|
94
|
+
model=self.model,
|
|
95
|
+
nativefmt=self.nativefmt,
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
def _geo2basename_info(self, add_stretching=True):
|
|
99
|
+
"""Particular geometry dictionnary for _AbstractLamBoundary class and derivated ones."""
|
|
100
|
+
if isinstance(self.geometry, LonlatGeometry):
|
|
101
|
+
lgeo = [self.geometry.area, self.geometry.rnice]
|
|
102
|
+
else:
|
|
103
|
+
lgeo = super()._geo2basename_info(add_stretching)
|
|
104
|
+
return lgeo
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
class LAMBoundary(_AbstractLAMBoundary):
|
|
108
|
+
"""
|
|
109
|
+
Class of a coupling file for a Limited Area Model.
|
|
110
|
+
A SpectralGeometry object is needed and the source model is given in the footprint.
|
|
111
|
+
"""
|
|
112
|
+
|
|
113
|
+
_footprint = dict(
|
|
114
|
+
attr = dict(
|
|
115
|
+
source = dict(
|
|
116
|
+
values = [
|
|
117
|
+
'arpege', 'aladin', 'arome', 'ifs', 'ecmwf', 'psy4',
|
|
118
|
+
'mercator_global', 'glo12', 'mfwam'
|
|
119
|
+
]
|
|
120
|
+
),
|
|
121
|
+
)
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
@property
|
|
125
|
+
def _mysrc(self):
|
|
126
|
+
return self.source
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
_a_source_cutoff = a_cutoff
|
|
130
|
+
del _a_source_cutoff['alias']
|
|
131
|
+
_a_source_cutoff['optional'] = True
|
|
132
|
+
_a_source_cutoff['default'] = 'production'
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
class EnhancedLAMBoundary(_AbstractLAMBoundary):
|
|
136
|
+
"""
|
|
137
|
+
Class of a coupling file for a Limited Area Model.
|
|
138
|
+
A SpectralGeometry object is needed and the source app, source conf and
|
|
139
|
+
source cutoff is given in the footprint.
|
|
140
|
+
"""
|
|
141
|
+
|
|
142
|
+
_footprint = dict(
|
|
143
|
+
attr = dict(
|
|
144
|
+
source_app = dict(),
|
|
145
|
+
source_conf = dict(),
|
|
146
|
+
source_cutoff = _a_source_cutoff,
|
|
147
|
+
)
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
@property
|
|
151
|
+
def _mysrc(self):
|
|
152
|
+
return [self.source_app, self.source_conf,
|
|
153
|
+
{'cutoff': self.source_cutoff}]
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
_abs_forcing_fp = footprints.DecorativeFootprint(
|
|
157
|
+
info='Coupling file for any offline model.',
|
|
158
|
+
attr=dict(
|
|
159
|
+
kind=dict(
|
|
160
|
+
values=['forcing', ],
|
|
161
|
+
),
|
|
162
|
+
filling=dict(),
|
|
163
|
+
source_app=dict(),
|
|
164
|
+
source_conf=dict(),
|
|
165
|
+
source_cutoff=_a_source_cutoff,
|
|
166
|
+
),
|
|
167
|
+
decorator=[namebuilding_insert('src', lambda s: [s.source_app, s.source_conf,
|
|
168
|
+
{'cutoff': s.source_cutoff}]),
|
|
169
|
+
overwrite_realkind('forcing'), ]
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
class _AbstractForcing(GeoFlowResource):
|
|
174
|
+
"""Abstract class for date-based coupling file for any offline model."""
|
|
175
|
+
|
|
176
|
+
_abstract = True
|
|
177
|
+
_footprint = [_abs_forcing_fp, ]
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
class _AbstractPeriodForcing(GeoPeriodFlowResource):
|
|
181
|
+
"""Abstract class for period-based coupling file for any offline model."""
|
|
182
|
+
|
|
183
|
+
_abstract = True
|
|
184
|
+
_footprint = [_abs_forcing_fp, ]
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
_abs_external_forcing_fp = footprints.DecorativeFootprint(
|
|
188
|
+
dict(
|
|
189
|
+
attr=dict(
|
|
190
|
+
model=dict(
|
|
191
|
+
outcast=['surfex', ],
|
|
192
|
+
),
|
|
193
|
+
),
|
|
194
|
+
),
|
|
195
|
+
decorator=[namebuilding_append('src', lambda s: s.filling)],
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
class ExternalForcing(_AbstractForcing):
|
|
200
|
+
"""Class for date-based coupling file for any offline model.
|
|
201
|
+
|
|
202
|
+
This class takes an optional **term** attribute.
|
|
203
|
+
"""
|
|
204
|
+
|
|
205
|
+
_footprint = [term_deco, _abs_external_forcing_fp]
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
class ExternalTimePeriodForcing(_AbstractForcing):
|
|
209
|
+
"""Class for date-based coupling file for any offline model.
|
|
210
|
+
|
|
211
|
+
This class needs a **begintime**/**endtime** attribute.
|
|
212
|
+
"""
|
|
213
|
+
|
|
214
|
+
_footprint = [timeperiod_deco, _abs_external_forcing_fp]
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
_abs_surfex_forcing_fp = footprints.DecorativeFootprint(
|
|
218
|
+
dict(
|
|
219
|
+
info='Coupling/Forcing file for Surfex.',
|
|
220
|
+
attr=dict(
|
|
221
|
+
model=dict(
|
|
222
|
+
values=['surfex', ],
|
|
223
|
+
),
|
|
224
|
+
filling=dict(
|
|
225
|
+
optional=True,
|
|
226
|
+
default='atm',
|
|
227
|
+
),
|
|
228
|
+
nativefmt=dict(
|
|
229
|
+
values=['netcdf', 'ascii', 'tar'],
|
|
230
|
+
default='netcdf',
|
|
231
|
+
),
|
|
232
|
+
)
|
|
233
|
+
),
|
|
234
|
+
decorator=[namebuilding_append('src',
|
|
235
|
+
lambda s: None if s.filling == 'atm' else s.filling,
|
|
236
|
+
none_discard=True)]
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
class SurfexForcing(_AbstractForcing):
|
|
241
|
+
"""Class for date-based coupling file for Surfex.
|
|
242
|
+
|
|
243
|
+
This class takes an optional **term** attribute.
|
|
244
|
+
"""
|
|
245
|
+
|
|
246
|
+
_footprint = [term_deco, _abs_surfex_forcing_fp, ]
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
class SurfexTimePeriodForcing(_AbstractForcing):
|
|
250
|
+
"""Class for date-based coupling file for Surfex.
|
|
251
|
+
|
|
252
|
+
This class needs a **begintime**/**endtime** attribute.
|
|
253
|
+
"""
|
|
254
|
+
|
|
255
|
+
_footprint = [timeperiod_deco, _abs_surfex_forcing_fp, ]
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
class SurfexPeriodForcing(_AbstractPeriodForcing):
|
|
259
|
+
"""Class for period-based coupling file for Surfex."""
|
|
260
|
+
|
|
261
|
+
_footprint = [_abs_surfex_forcing_fp, ]
|