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,96 @@
1
+ """
2
+ TODO: Module documentation.
3
+ """
4
+
5
+ from vortex.data.outflow import StaticResource
6
+ from vortex.data.flow import GeoFlowResource
7
+ from vortex.syntax.stdattrs import date_deco, cutoff_deco
8
+ from vortex.syntax.stddeco import namebuilding_delete, namebuilding_insert
9
+
10
+ #: No automatic export
11
+ __all__ = []
12
+
13
+
14
+ @namebuilding_insert('radical', lambda s: s.fields)
15
+ @namebuilding_insert('src', lambda s: [s.origin, ])
16
+ @namebuilding_delete('fmt')
17
+ class RawFields(StaticResource):
18
+
19
+ _footprint = [
20
+ date_deco, cutoff_deco,
21
+ dict(
22
+ info = 'File containing a limited list of observations fields',
23
+ attr = dict(
24
+ kind = dict(
25
+ values = ['rawfields']
26
+ ),
27
+ origin = dict(
28
+ values = [
29
+ 'bdm', 'nesdis', 'ostia', 'psy4',
30
+ 'mercator_global', 'bdpe', 'safosi',
31
+ 'safosi_hn', 'safosi_hs',
32
+ ]
33
+ ),
34
+ fields = dict(
35
+ values = ['sst', 'seaice', 'ocean', 'seaice_conc', 'seaice_thick']
36
+ ),
37
+ )
38
+ )
39
+ ]
40
+
41
+ @property
42
+ def realkind(self):
43
+ return 'rawfields'
44
+
45
+ def olive_basename(self):
46
+ if self.origin == 'nesdis' and self.fields == 'sst':
47
+ bname = '.'.join((self.fields, self.origin, 'bdap'))
48
+ elif self.fields == 'seaice':
49
+ bname = 'ice_concent'
50
+ else:
51
+ bname = '.'.join((self.fields, self.origin))
52
+ return bname
53
+
54
+ def archive_basename(self):
55
+ if self.origin == 'nesdis' and self.fields == 'sst':
56
+ bname = '.'.join((self.fields, self.origin, 'bdap'))
57
+ elif self.fields == 'seaice':
58
+ bname = 'ice_concent'
59
+ else:
60
+ bname = '.'.join((self.fields, self.origin))
61
+ return bname
62
+
63
+
64
+ @namebuilding_insert('radical', lambda s: s.fields)
65
+ class GeoFields(GeoFlowResource):
66
+
67
+ _footprint = [
68
+ dict(
69
+ info = 'File containing a limited list of fields in a specific geometry',
70
+ attr = dict(
71
+ kind = dict(
72
+ values = ['geofields']
73
+ ),
74
+ fields = dict(
75
+ values = ['sst', 'seaice', 'ocean', 'seaice_conc', 'seaice_thick']
76
+ ),
77
+ nativefmt = dict(
78
+ values = ['fa'],
79
+ default = 'fa'
80
+ ),
81
+ )
82
+ )
83
+ ]
84
+
85
+ @property
86
+ def realkind(self):
87
+ return 'geofields'
88
+
89
+ def olive_basename(self):
90
+ bname = 'icmshanal' + self.fields
91
+ if self.fields == 'seaice':
92
+ bname = bname.upper()
93
+ return bname
94
+
95
+ def archive_basename(self):
96
+ return 'icmshanal' + self.fields
@@ -0,0 +1,308 @@
1
+ """
2
+ Resources associated with the handling of gridded data (other than full model states).
3
+ """
4
+
5
+ import re
6
+
7
+ from bronx.stdtypes.date import Time
8
+ import footprints
9
+
10
+ from vortex.data.contents import JsonDictContent
11
+ from vortex.data.flow import GeoFlowResource, FlowResource
12
+ from vortex.syntax.stdattrs import term_deco, timeperiod_deco
13
+ from vortex.syntax.stddeco import namebuilding_insert
14
+ from vortex.tools import env
15
+
16
+ #: No automatic export
17
+ __all__ = []
18
+
19
+
20
+ _ORIGIN_INFO = """Describes where the data originaly comes from. The most common
21
+ values are: ana (that stands for analysis), fcst (that stands for
22
+ forecast), hst (that stands for Historic file. i.e a file that contains a
23
+ full model state variable), stat_ad (that stands for statistical adapatation)."""
24
+ _ORIGIN_INFO = _ORIGIN_INFO.replace('\n', ' ')
25
+
26
+
27
+ class AbstractGridpoint(GeoFlowResource):
28
+ """Gridpoint file calculated in a post-processing task or module.
29
+
30
+ * Possible formats are 'grib', 'fa' or 'netcdf'.
31
+ * A gridpoint file can be calculated for files from different sources given
32
+ by the "origin" attribute.
33
+
34
+ """
35
+
36
+ _abstract = True
37
+ _footprint = dict(
38
+ info = 'Any kind of GridPoint file.',
39
+ attr = dict(
40
+ origin = dict(
41
+ info = _ORIGIN_INFO,
42
+ values = [
43
+ 'analyse', 'ana', 'guess', 'gss', 'arpege', 'arp', 'arome', 'aro',
44
+ 'aladin', 'ald', 'historic', 'hst', 'forecast', 'fcst', 'era40', 'e40',
45
+ 'era15', 'e15', 'interp', 'sumo', 'filter', 'stat_ad',
46
+ ],
47
+ remap = dict(
48
+ analyse = 'ana',
49
+ guess = 'gss',
50
+ arpege = 'arp',
51
+ aladin = 'ald',
52
+ arome = 'aro',
53
+ historic = 'hst',
54
+ forecast = 'fcst',
55
+ era40 = 'e40',
56
+ era15 = 'e15'
57
+ )
58
+ ),
59
+ kind = dict(
60
+ values = ['gridpoint', 'gribfile', 'fullpos'],
61
+ remap = dict(
62
+ fullpos = 'gridpoint'
63
+ )
64
+ ),
65
+ nativefmt = dict(
66
+ values = ['grib', 'grib1', 'grib2', 'netcdf', 'fa'],
67
+ ),
68
+ filtername = dict(
69
+ # Dummy argument but avoid priority related messages with footprints
70
+ info = 'With GridPoint files, leave filtername empty...',
71
+ optional = True,
72
+ values = [None, ],
73
+ ),
74
+ )
75
+ )
76
+
77
+ @property
78
+ def realkind(self):
79
+ return 'gridpoint'
80
+
81
+ def olive_basename(self):
82
+ """OLIVE specific naming convention (abstract)."""
83
+ pass
84
+
85
+ def archive_basename(self):
86
+ """OP ARCHIVE specific naming convention (abstract)."""
87
+ pass
88
+
89
+ def namebuilding_info(self):
90
+ """Generic information, radical = ``grid``."""
91
+ ninfo = super().namebuilding_info()
92
+ if self.origin in ('stat_ad', ):
93
+ # For new ``origin`` please use this code path... Please, no more
94
+ # weird logic like the one hard-coded in the else statement !
95
+ source = self.origin
96
+ else:
97
+ if self.model == 'mocage':
98
+ if self.origin == 'hst':
99
+ source = 'forecast'
100
+ else:
101
+ source = 'sumo'
102
+ elif self.model in ('hycom', 'mfwam'):
103
+ if self.origin == 'ana':
104
+ source = 'analysis'
105
+ else:
106
+ source = 'forecast'
107
+ else:
108
+ source = 'forecast'
109
+ ninfo.update(
110
+ radical='grid',
111
+ src=[self.model, source],
112
+ )
113
+ return ninfo
114
+
115
+ def iga_pathinfo(self):
116
+ """Standard path information for IGA inline cache."""
117
+ directory = dict(
118
+ fa='fic_day',
119
+ grib='bdap'
120
+ )
121
+ return dict(
122
+ fmt=directory[self.nativefmt],
123
+ nativefmt=self.nativefmt,
124
+ model=self.model,
125
+ )
126
+
127
+
128
+ class GridPoint(AbstractGridpoint):
129
+ """
130
+ Gridpoint files calculated in a post-processing task or module for
131
+ a single-term.
132
+ """
133
+
134
+ _abstract = True
135
+ _footprint = [term_deco, ]
136
+
137
+
138
+ class TimePeriodGridPoint(AbstractGridpoint):
139
+ """
140
+ Gridpoint files calculated in a post-processing task or module for
141
+ a given time period.
142
+ """
143
+
144
+ _abstract = True
145
+ _footprint = [
146
+ timeperiod_deco,
147
+ dict(
148
+ attr = dict(
149
+ begintime = dict(
150
+ optional = True,
151
+ default = Time(0),
152
+ )
153
+ )
154
+ )
155
+ ]
156
+
157
+
158
+ # A bunch of generic footprint declaration to ease with class creation
159
+ _NATIVEFMT_FULLPOS_FP = footprints.Footprint(
160
+ info='Abstract nativefmt for fullpos files.',
161
+ attr=dict(nativefmt=dict(values=['fa'],
162
+ default='fa', ))
163
+ )
164
+ _NATIVEFMT_GENERIC_FP = footprints.Footprint(
165
+ info='Abstract nativefmt for any other gridpoint files.',
166
+ attr=dict(nativefmt=dict(values=['grib', 'grib1', 'grib2', 'netcdf'],
167
+ default='grib'))
168
+ )
169
+ _FILTERNAME_AWARE_FPDECO = footprints.DecorativeFootprint(
170
+ footprints.Footprint(
171
+ info='Abstract filtering attribute (used when the filtername attribute is allowed).',
172
+ attr=dict(filtername=dict(info="The filter used to obtain this data.",
173
+ optional=False, values=[],))),
174
+ decorator=[namebuilding_insert('filtername', lambda s: s.filtername), ]
175
+ )
176
+
177
+
178
+ class GridPointMap(FlowResource):
179
+ """Map of the gridpoint files as produced by fullpos."""
180
+
181
+ _footprint = dict(
182
+ info = 'Gridpoint Files Map',
183
+ attr = dict(
184
+ kind = dict(
185
+ values = ['gridpointmap', 'gribfilemap', 'fullposmap'],
186
+ remap = dict(fullposmap = 'gridpointmap', )
187
+ ),
188
+ clscontents = dict(
189
+ default = JsonDictContent,
190
+ ),
191
+ nativefmt = dict(
192
+ values = ['json'],
193
+ default = 'json',
194
+ ),
195
+ )
196
+ )
197
+
198
+ @property
199
+ def realkind(self):
200
+ return 'gridpointmap'
201
+
202
+
203
+ class GridPointFullPos(GridPoint):
204
+ """Gridpoint file produced by FullPos in ``fa`` format."""
205
+
206
+ _footprint = [
207
+ _NATIVEFMT_FULLPOS_FP,
208
+ dict(info='GridPoint file produced by Fullpos (with a single term)'),
209
+ ]
210
+
211
+ def olive_basename(self):
212
+ """OLIVE specific naming convention."""
213
+
214
+ t = self.term.hour
215
+ e = env.current()
216
+ if 'VORTEX_ANA_TERMSHIFT' not in e and self.origin == 'ana':
217
+ t = 0
218
+
219
+ name = None
220
+ if self.model == 'mocage':
221
+ if self.origin == 'hst':
222
+ name = 'HM' + self.geometry.area + '+' + self.term.fmthour
223
+ elif self.origin == 'sumo':
224
+ deltastr = 'PT{!s}H'.format(self.term.hour)
225
+ deltadate = self.date + deltastr
226
+ name = 'SM' + self.geometry.area + '_void' + '+' + deltadate.ymd
227
+ elif self.origin == 'interp':
228
+ deltastr = 'PT{!s}H'.format(self.term.hour)
229
+ deltadate = self.date + deltastr
230
+ name = 'SM' + self.geometry.area + '_interp' + '+' + deltadate.ymd
231
+ else:
232
+ name = 'PFFPOS' + self.origin.upper() + self.geometry.area + '+' + self.term.nice(t)
233
+
234
+ if name is None:
235
+ raise ValueError('Could not build a proper olive name: {!s}'.format(self))
236
+
237
+ return name
238
+
239
+ def archive_basename(self):
240
+ """OP ARCHIVE specific naming convention."""
241
+
242
+ deltastr = 'PT{!s}H'.format(self.term.hour)
243
+ deltadate = self.date + deltastr
244
+
245
+ name = None
246
+ if self.origin == 'hst':
247
+ if self.model == 'ifs':
248
+ name = 'PFFPOS' + self.geometry.area + '+' + self.term.fmthour
249
+ else:
250
+ name = 'HM' + self.geometry.area + '+' + deltadate.ymdh
251
+ elif self.origin == 'interp':
252
+ name = 'SM' + self.geometry.area + '+' + deltadate.ymd
253
+
254
+ if name is None:
255
+ raise ValueError('Could not build a proper archive name: {!s}'.format(self))
256
+
257
+ return name
258
+
259
+
260
+ class GridPointExport(GridPoint):
261
+ """Generic single term gridpoint file using a standard format."""
262
+
263
+ _footprint = [
264
+ _NATIVEFMT_GENERIC_FP,
265
+ dict(info='Generic gridpoint file (with a single term)'),
266
+ ]
267
+
268
+ def olive_basename(self):
269
+ """OLIVE specific naming convention."""
270
+
271
+ t = self.term.hour
272
+ e = env.current()
273
+ if 'VORTEX_ANA_TERMSHIFT' not in e and self.origin == 'ana':
274
+ t = 0
275
+ return 'GRID' + self.origin.upper() + self.geometry.area + '+' + self.term.nice(t)
276
+
277
+ def archive_basename(self):
278
+ """OP ARCHIVE specific naming convention."""
279
+
280
+ name = None
281
+ if re.match('aladin|arome', self.model):
282
+ name = 'GRID' + self.geometry.area + 'r{!s}'.format(self.date.hour) + '_' + self.term.fmthour
283
+ elif re.match('arp|hycom|surcotes', self.model):
284
+ name = '(gribfix:igakey)'
285
+ elif self.model == 'ifs':
286
+ deltastr = 'PT{!s}H'.format(self.term.hour)
287
+ deltadate = self.date + deltastr
288
+ name = 'MET' + deltadate.ymd + '.' + self.geometry.area + '.grb'
289
+
290
+ if name is None:
291
+ raise ValueError('Could not build a proper archive name: {!s}'.format(self))
292
+
293
+ return name
294
+
295
+
296
+ class FilteredGridPointExport(GridPointExport):
297
+ """Generic single term gridpoint file using a standard format."""
298
+ _footprint = [_FILTERNAME_AWARE_FPDECO, ]
299
+
300
+
301
+ class TimePeriodGridPointExport(TimePeriodGridPoint):
302
+ """Generic multi term gridpoint file using a standard format."""
303
+ _footprint = [_NATIVEFMT_GENERIC_FP, ]
304
+
305
+
306
+ class FilteredTimePeriodGridPointExport(TimePeriodGridPointExport):
307
+ """Generic multi term gridpoint file using a standard format."""
308
+ _footprint = [_FILTERNAME_AWARE_FPDECO, ]