vortex-nwp 2.0.0__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 (144) hide show
  1. vortex/__init__.py +159 -0
  2. vortex/algo/__init__.py +13 -0
  3. vortex/algo/components.py +2462 -0
  4. vortex/algo/mpitools.py +1953 -0
  5. vortex/algo/mpitools_templates/__init__.py +1 -0
  6. vortex/algo/mpitools_templates/envelope_wrapper_default.tpl +27 -0
  7. vortex/algo/mpitools_templates/envelope_wrapper_mpiauto.tpl +29 -0
  8. vortex/algo/mpitools_templates/wrapstd_wrapper_default.tpl +18 -0
  9. vortex/algo/serversynctools.py +171 -0
  10. vortex/config.py +112 -0
  11. vortex/data/__init__.py +19 -0
  12. vortex/data/abstractstores.py +1510 -0
  13. vortex/data/containers.py +835 -0
  14. vortex/data/contents.py +622 -0
  15. vortex/data/executables.py +275 -0
  16. vortex/data/flow.py +119 -0
  17. vortex/data/geometries.ini +2689 -0
  18. vortex/data/geometries.py +799 -0
  19. vortex/data/handlers.py +1230 -0
  20. vortex/data/outflow.py +67 -0
  21. vortex/data/providers.py +487 -0
  22. vortex/data/resources.py +207 -0
  23. vortex/data/stores.py +1390 -0
  24. vortex/data/sync_templates/__init__.py +0 -0
  25. vortex/gloves.py +309 -0
  26. vortex/layout/__init__.py +20 -0
  27. vortex/layout/contexts.py +577 -0
  28. vortex/layout/dataflow.py +1220 -0
  29. vortex/layout/monitor.py +969 -0
  30. vortex/nwp/__init__.py +14 -0
  31. vortex/nwp/algo/__init__.py +21 -0
  32. vortex/nwp/algo/assim.py +537 -0
  33. vortex/nwp/algo/clim.py +1086 -0
  34. vortex/nwp/algo/coupling.py +831 -0
  35. vortex/nwp/algo/eda.py +840 -0
  36. vortex/nwp/algo/eps.py +785 -0
  37. vortex/nwp/algo/forecasts.py +886 -0
  38. vortex/nwp/algo/fpserver.py +1303 -0
  39. vortex/nwp/algo/ifsnaming.py +463 -0
  40. vortex/nwp/algo/ifsroot.py +404 -0
  41. vortex/nwp/algo/monitoring.py +263 -0
  42. vortex/nwp/algo/mpitools.py +694 -0
  43. vortex/nwp/algo/odbtools.py +1258 -0
  44. vortex/nwp/algo/oopsroot.py +916 -0
  45. vortex/nwp/algo/oopstests.py +220 -0
  46. vortex/nwp/algo/request.py +660 -0
  47. vortex/nwp/algo/stdpost.py +1641 -0
  48. vortex/nwp/data/__init__.py +30 -0
  49. vortex/nwp/data/assim.py +380 -0
  50. vortex/nwp/data/boundaries.py +314 -0
  51. vortex/nwp/data/climfiles.py +521 -0
  52. vortex/nwp/data/configfiles.py +153 -0
  53. vortex/nwp/data/consts.py +954 -0
  54. vortex/nwp/data/ctpini.py +149 -0
  55. vortex/nwp/data/diagnostics.py +209 -0
  56. vortex/nwp/data/eda.py +147 -0
  57. vortex/nwp/data/eps.py +432 -0
  58. vortex/nwp/data/executables.py +1045 -0
  59. vortex/nwp/data/fields.py +111 -0
  60. vortex/nwp/data/gridfiles.py +380 -0
  61. vortex/nwp/data/logs.py +584 -0
  62. vortex/nwp/data/modelstates.py +363 -0
  63. vortex/nwp/data/monitoring.py +193 -0
  64. vortex/nwp/data/namelists.py +696 -0
  65. vortex/nwp/data/obs.py +840 -0
  66. vortex/nwp/data/oopsexec.py +74 -0
  67. vortex/nwp/data/providers.py +207 -0
  68. vortex/nwp/data/query.py +206 -0
  69. vortex/nwp/data/stores.py +160 -0
  70. vortex/nwp/data/surfex.py +337 -0
  71. vortex/nwp/syntax/__init__.py +9 -0
  72. vortex/nwp/syntax/stdattrs.py +437 -0
  73. vortex/nwp/tools/__init__.py +10 -0
  74. vortex/nwp/tools/addons.py +40 -0
  75. vortex/nwp/tools/agt.py +67 -0
  76. vortex/nwp/tools/bdap.py +59 -0
  77. vortex/nwp/tools/bdcp.py +41 -0
  78. vortex/nwp/tools/bdm.py +24 -0
  79. vortex/nwp/tools/bdmp.py +54 -0
  80. vortex/nwp/tools/conftools.py +1661 -0
  81. vortex/nwp/tools/drhook.py +66 -0
  82. vortex/nwp/tools/grib.py +294 -0
  83. vortex/nwp/tools/gribdiff.py +104 -0
  84. vortex/nwp/tools/ifstools.py +203 -0
  85. vortex/nwp/tools/igastuff.py +273 -0
  86. vortex/nwp/tools/mars.py +68 -0
  87. vortex/nwp/tools/odb.py +657 -0
  88. vortex/nwp/tools/partitioning.py +258 -0
  89. vortex/nwp/tools/satrad.py +71 -0
  90. vortex/nwp/util/__init__.py +6 -0
  91. vortex/nwp/util/async.py +212 -0
  92. vortex/nwp/util/beacon.py +40 -0
  93. vortex/nwp/util/diffpygram.py +447 -0
  94. vortex/nwp/util/ens.py +279 -0
  95. vortex/nwp/util/hooks.py +139 -0
  96. vortex/nwp/util/taskdeco.py +85 -0
  97. vortex/nwp/util/usepygram.py +697 -0
  98. vortex/nwp/util/usetnt.py +101 -0
  99. vortex/proxy.py +6 -0
  100. vortex/sessions.py +374 -0
  101. vortex/syntax/__init__.py +9 -0
  102. vortex/syntax/stdattrs.py +867 -0
  103. vortex/syntax/stddeco.py +185 -0
  104. vortex/toolbox.py +1117 -0
  105. vortex/tools/__init__.py +20 -0
  106. vortex/tools/actions.py +523 -0
  107. vortex/tools/addons.py +316 -0
  108. vortex/tools/arm.py +96 -0
  109. vortex/tools/compression.py +325 -0
  110. vortex/tools/date.py +27 -0
  111. vortex/tools/ddhpack.py +10 -0
  112. vortex/tools/delayedactions.py +782 -0
  113. vortex/tools/env.py +541 -0
  114. vortex/tools/folder.py +834 -0
  115. vortex/tools/grib.py +738 -0
  116. vortex/tools/lfi.py +953 -0
  117. vortex/tools/listings.py +423 -0
  118. vortex/tools/names.py +637 -0
  119. vortex/tools/net.py +2124 -0
  120. vortex/tools/odb.py +10 -0
  121. vortex/tools/parallelism.py +368 -0
  122. vortex/tools/prestaging.py +210 -0
  123. vortex/tools/rawfiles.py +10 -0
  124. vortex/tools/schedulers.py +480 -0
  125. vortex/tools/services.py +940 -0
  126. vortex/tools/storage.py +996 -0
  127. vortex/tools/surfex.py +61 -0
  128. vortex/tools/systems.py +3976 -0
  129. vortex/tools/targets.py +440 -0
  130. vortex/util/__init__.py +9 -0
  131. vortex/util/config.py +1122 -0
  132. vortex/util/empty.py +24 -0
  133. vortex/util/helpers.py +216 -0
  134. vortex/util/introspection.py +69 -0
  135. vortex/util/iosponge.py +80 -0
  136. vortex/util/roles.py +49 -0
  137. vortex/util/storefunctions.py +129 -0
  138. vortex/util/structs.py +26 -0
  139. vortex/util/worker.py +162 -0
  140. vortex_nwp-2.0.0.dist-info/METADATA +67 -0
  141. vortex_nwp-2.0.0.dist-info/RECORD +144 -0
  142. vortex_nwp-2.0.0.dist-info/WHEEL +5 -0
  143. vortex_nwp-2.0.0.dist-info/licenses/LICENSE +517 -0
  144. vortex_nwp-2.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,111 @@
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(
16
+ "src",
17
+ lambda s: [
18
+ s.origin,
19
+ ],
20
+ )
21
+ @namebuilding_delete("fmt")
22
+ class RawFields(StaticResource):
23
+ _footprint = [
24
+ date_deco,
25
+ cutoff_deco,
26
+ dict(
27
+ info="File containing a limited list of observations fields",
28
+ attr=dict(
29
+ kind=dict(values=["rawfields"]),
30
+ origin=dict(
31
+ values=[
32
+ "bdm",
33
+ "nesdis",
34
+ "ostia",
35
+ "psy4",
36
+ "mercator_global",
37
+ "bdpe",
38
+ "safosi",
39
+ "safosi_hn",
40
+ "safosi_hs",
41
+ ]
42
+ ),
43
+ fields=dict(
44
+ values=[
45
+ "sst",
46
+ "seaice",
47
+ "ocean",
48
+ "seaice_conc",
49
+ "seaice_thick",
50
+ ]
51
+ ),
52
+ ),
53
+ ),
54
+ ]
55
+
56
+ @property
57
+ def realkind(self):
58
+ return "rawfields"
59
+
60
+ def olive_basename(self):
61
+ if self.origin == "nesdis" and self.fields == "sst":
62
+ bname = ".".join((self.fields, self.origin, "bdap"))
63
+ elif self.fields == "seaice":
64
+ bname = "ice_concent"
65
+ else:
66
+ bname = ".".join((self.fields, self.origin))
67
+ return bname
68
+
69
+ def archive_basename(self):
70
+ if self.origin == "nesdis" and self.fields == "sst":
71
+ bname = ".".join((self.fields, self.origin, "bdap"))
72
+ elif self.fields == "seaice":
73
+ bname = "ice_concent"
74
+ else:
75
+ bname = ".".join((self.fields, self.origin))
76
+ return bname
77
+
78
+
79
+ @namebuilding_insert("radical", lambda s: s.fields)
80
+ class GeoFields(GeoFlowResource):
81
+ _footprint = [
82
+ dict(
83
+ info="File containing a limited list of fields in a specific geometry",
84
+ attr=dict(
85
+ kind=dict(values=["geofields"]),
86
+ fields=dict(
87
+ values=[
88
+ "sst",
89
+ "seaice",
90
+ "ocean",
91
+ "seaice_conc",
92
+ "seaice_thick",
93
+ ]
94
+ ),
95
+ nativefmt=dict(values=["fa"], default="fa"),
96
+ ),
97
+ )
98
+ ]
99
+
100
+ @property
101
+ def realkind(self):
102
+ return "geofields"
103
+
104
+ def olive_basename(self):
105
+ bname = "icmshanal" + self.fields
106
+ if self.fields == "seaice":
107
+ bname = bname.upper()
108
+ return bname
109
+
110
+ def archive_basename(self):
111
+ return "icmshanal" + self.fields
@@ -0,0 +1,380 @@
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",
44
+ "ana",
45
+ "guess",
46
+ "gss",
47
+ "arpege",
48
+ "arp",
49
+ "arome",
50
+ "aro",
51
+ "aladin",
52
+ "ald",
53
+ "historic",
54
+ "hst",
55
+ "forecast",
56
+ "fcst",
57
+ "era40",
58
+ "e40",
59
+ "era15",
60
+ "e15",
61
+ "interp",
62
+ "sumo",
63
+ "filter",
64
+ "stat_ad",
65
+ ],
66
+ remap=dict(
67
+ analyse="ana",
68
+ guess="gss",
69
+ arpege="arp",
70
+ aladin="ald",
71
+ arome="aro",
72
+ historic="hst",
73
+ forecast="fcst",
74
+ era40="e40",
75
+ era15="e15",
76
+ ),
77
+ ),
78
+ kind=dict(
79
+ values=["gridpoint", "gribfile", "fullpos"],
80
+ remap=dict(fullpos="gridpoint"),
81
+ ),
82
+ nativefmt=dict(
83
+ values=["grib", "grib1", "grib2", "netcdf", "fa"],
84
+ ),
85
+ filtername=dict(
86
+ # Dummy argument but avoid priority related messages with footprints
87
+ info="With GridPoint files, leave filtername empty...",
88
+ optional=True,
89
+ values=[
90
+ None,
91
+ ],
92
+ ),
93
+ ),
94
+ )
95
+
96
+ @property
97
+ def realkind(self):
98
+ return "gridpoint"
99
+
100
+ def olive_basename(self):
101
+ """OLIVE specific naming convention (abstract)."""
102
+ pass
103
+
104
+ def archive_basename(self):
105
+ """OP ARCHIVE specific naming convention (abstract)."""
106
+ pass
107
+
108
+ def namebuilding_info(self):
109
+ """Generic information, radical = ``grid``."""
110
+ ninfo = super().namebuilding_info()
111
+ if self.origin in ("stat_ad",):
112
+ # For new ``origin`` please use this code path... Please, no more
113
+ # weird logic like the one hard-coded in the else statement !
114
+ source = self.origin
115
+ else:
116
+ if self.model == "mocage":
117
+ if self.origin == "hst":
118
+ source = "forecast"
119
+ else:
120
+ source = "sumo"
121
+ elif self.model in ("hycom", "mfwam"):
122
+ if self.origin == "ana":
123
+ source = "analysis"
124
+ else:
125
+ source = "forecast"
126
+ else:
127
+ source = "forecast"
128
+ ninfo.update(
129
+ radical="grid",
130
+ src=[self.model, source],
131
+ )
132
+ return ninfo
133
+
134
+ def iga_pathinfo(self):
135
+ """Standard path information for IGA inline cache."""
136
+ directory = dict(fa="fic_day", grib="bdap")
137
+ return dict(
138
+ fmt=directory[self.nativefmt],
139
+ nativefmt=self.nativefmt,
140
+ model=self.model,
141
+ )
142
+
143
+
144
+ class GridPoint(AbstractGridpoint):
145
+ """
146
+ Gridpoint files calculated in a post-processing task or module for
147
+ a single-term.
148
+ """
149
+
150
+ _abstract = True
151
+ _footprint = [
152
+ term_deco,
153
+ ]
154
+
155
+
156
+ class TimePeriodGridPoint(AbstractGridpoint):
157
+ """
158
+ Gridpoint files calculated in a post-processing task or module for
159
+ a given time period.
160
+ """
161
+
162
+ _abstract = True
163
+ _footprint = [
164
+ timeperiod_deco,
165
+ dict(
166
+ attr=dict(
167
+ begintime=dict(
168
+ optional=True,
169
+ default=Time(0),
170
+ )
171
+ )
172
+ ),
173
+ ]
174
+
175
+
176
+ # A bunch of generic footprint declaration to ease with class creation
177
+ _NATIVEFMT_FULLPOS_FP = footprints.Footprint(
178
+ info="Abstract nativefmt for fullpos files.",
179
+ attr=dict(
180
+ nativefmt=dict(
181
+ values=["fa"],
182
+ default="fa",
183
+ )
184
+ ),
185
+ )
186
+ _NATIVEFMT_GENERIC_FP = footprints.Footprint(
187
+ info="Abstract nativefmt for any other gridpoint files.",
188
+ attr=dict(
189
+ nativefmt=dict(
190
+ values=["grib", "grib1", "grib2", "netcdf"], default="grib"
191
+ )
192
+ ),
193
+ )
194
+ _FILTERNAME_AWARE_FPDECO = footprints.DecorativeFootprint(
195
+ footprints.Footprint(
196
+ info="Abstract filtering attribute (used when the filtername attribute is allowed).",
197
+ attr=dict(
198
+ filtername=dict(
199
+ info="The filter used to obtain this data.",
200
+ optional=False,
201
+ values=[],
202
+ )
203
+ ),
204
+ ),
205
+ decorator=[
206
+ namebuilding_insert("filtername", lambda s: s.filtername),
207
+ ],
208
+ )
209
+
210
+
211
+ class GridPointMap(FlowResource):
212
+ """Map of the gridpoint files as produced by fullpos."""
213
+
214
+ _footprint = dict(
215
+ info="Gridpoint Files Map",
216
+ attr=dict(
217
+ kind=dict(
218
+ values=["gridpointmap", "gribfilemap", "fullposmap"],
219
+ remap=dict(
220
+ fullposmap="gridpointmap",
221
+ ),
222
+ ),
223
+ clscontents=dict(
224
+ default=JsonDictContent,
225
+ ),
226
+ nativefmt=dict(
227
+ values=["json"],
228
+ default="json",
229
+ ),
230
+ ),
231
+ )
232
+
233
+ @property
234
+ def realkind(self):
235
+ return "gridpointmap"
236
+
237
+
238
+ class GridPointFullPos(GridPoint):
239
+ """Gridpoint file produced by FullPos in ``fa`` format."""
240
+
241
+ _footprint = [
242
+ _NATIVEFMT_FULLPOS_FP,
243
+ dict(info="GridPoint file produced by Fullpos (with a single term)"),
244
+ ]
245
+
246
+ def olive_basename(self):
247
+ """OLIVE specific naming convention."""
248
+
249
+ t = self.term.hour
250
+ e = env.current()
251
+ if "VORTEX_ANA_TERMSHIFT" not in e and self.origin == "ana":
252
+ t = 0
253
+
254
+ name = None
255
+ if self.model == "mocage":
256
+ if self.origin == "hst":
257
+ name = "HM" + self.geometry.area + "+" + self.term.fmthour
258
+ elif self.origin == "sumo":
259
+ deltastr = "PT{!s}H".format(self.term.hour)
260
+ deltadate = self.date + deltastr
261
+ name = (
262
+ "SM" + self.geometry.area + "_void" + "+" + deltadate.ymd
263
+ )
264
+ elif self.origin == "interp":
265
+ deltastr = "PT{!s}H".format(self.term.hour)
266
+ deltadate = self.date + deltastr
267
+ name = (
268
+ "SM" + self.geometry.area + "_interp" + "+" + deltadate.ymd
269
+ )
270
+ else:
271
+ name = (
272
+ "PFFPOS"
273
+ + self.origin.upper()
274
+ + self.geometry.area
275
+ + "+"
276
+ + self.term.nice(t)
277
+ )
278
+
279
+ if name is None:
280
+ raise ValueError(
281
+ "Could not build a proper olive name: {!s}".format(self)
282
+ )
283
+
284
+ return name
285
+
286
+ def archive_basename(self):
287
+ """OP ARCHIVE specific naming convention."""
288
+
289
+ deltastr = "PT{!s}H".format(self.term.hour)
290
+ deltadate = self.date + deltastr
291
+
292
+ name = None
293
+ if self.origin == "hst":
294
+ if self.model == "ifs":
295
+ name = "PFFPOS" + self.geometry.area + "+" + self.term.fmthour
296
+ else:
297
+ name = "HM" + self.geometry.area + "+" + deltadate.ymdh
298
+ elif self.origin == "interp":
299
+ name = "SM" + self.geometry.area + "+" + deltadate.ymd
300
+
301
+ if name is None:
302
+ raise ValueError(
303
+ "Could not build a proper archive name: {!s}".format(self)
304
+ )
305
+
306
+ return name
307
+
308
+
309
+ class GridPointExport(GridPoint):
310
+ """Generic single term gridpoint file using a standard format."""
311
+
312
+ _footprint = [
313
+ _NATIVEFMT_GENERIC_FP,
314
+ dict(info="Generic gridpoint file (with a single term)"),
315
+ ]
316
+
317
+ def olive_basename(self):
318
+ """OLIVE specific naming convention."""
319
+
320
+ t = self.term.hour
321
+ e = env.current()
322
+ if "VORTEX_ANA_TERMSHIFT" not in e and self.origin == "ana":
323
+ t = 0
324
+ return (
325
+ "GRID"
326
+ + self.origin.upper()
327
+ + self.geometry.area
328
+ + "+"
329
+ + self.term.nice(t)
330
+ )
331
+
332
+ def archive_basename(self):
333
+ """OP ARCHIVE specific naming convention."""
334
+
335
+ name = None
336
+ if re.match("aladin|arome", self.model):
337
+ name = (
338
+ "GRID"
339
+ + self.geometry.area
340
+ + "r{!s}".format(self.date.hour)
341
+ + "_"
342
+ + self.term.fmthour
343
+ )
344
+ elif re.match("arp|hycom|surcotes", self.model):
345
+ name = "(gribfix:igakey)"
346
+ elif self.model == "ifs":
347
+ deltastr = "PT{!s}H".format(self.term.hour)
348
+ deltadate = self.date + deltastr
349
+ name = "MET" + deltadate.ymd + "." + self.geometry.area + ".grb"
350
+
351
+ if name is None:
352
+ raise ValueError(
353
+ "Could not build a proper archive name: {!s}".format(self)
354
+ )
355
+
356
+ return name
357
+
358
+
359
+ class FilteredGridPointExport(GridPointExport):
360
+ """Generic single term gridpoint file using a standard format."""
361
+
362
+ _footprint = [
363
+ _FILTERNAME_AWARE_FPDECO,
364
+ ]
365
+
366
+
367
+ class TimePeriodGridPointExport(TimePeriodGridPoint):
368
+ """Generic multi term gridpoint file using a standard format."""
369
+
370
+ _footprint = [
371
+ _NATIVEFMT_GENERIC_FP,
372
+ ]
373
+
374
+
375
+ class FilteredTimePeriodGridPointExport(TimePeriodGridPointExport):
376
+ """Generic multi term gridpoint file using a standard format."""
377
+
378
+ _footprint = [
379
+ _FILTERNAME_AWARE_FPDECO,
380
+ ]