vortex-nwp 2.0.0b1__py3-none-any.whl → 2.1.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 (141) hide show
  1. vortex/__init__.py +75 -47
  2. vortex/algo/__init__.py +3 -2
  3. vortex/algo/components.py +944 -618
  4. vortex/algo/mpitools.py +802 -497
  5. vortex/algo/mpitools_templates/__init__.py +1 -0
  6. vortex/algo/serversynctools.py +34 -33
  7. vortex/config.py +19 -22
  8. vortex/data/__init__.py +9 -3
  9. vortex/data/abstractstores.py +593 -655
  10. vortex/data/containers.py +217 -162
  11. vortex/data/contents.py +65 -39
  12. vortex/data/executables.py +93 -102
  13. vortex/data/flow.py +40 -34
  14. vortex/data/geometries.py +228 -132
  15. vortex/data/handlers.py +436 -227
  16. vortex/data/outflow.py +15 -15
  17. vortex/data/providers.py +185 -163
  18. vortex/data/resources.py +48 -42
  19. vortex/data/stores.py +540 -417
  20. vortex/data/sync_templates/__init__.py +0 -0
  21. vortex/gloves.py +114 -87
  22. vortex/layout/__init__.py +1 -8
  23. vortex/layout/contexts.py +150 -84
  24. vortex/layout/dataflow.py +353 -202
  25. vortex/layout/monitor.py +264 -128
  26. vortex/nwp/__init__.py +5 -2
  27. vortex/nwp/algo/__init__.py +14 -5
  28. vortex/nwp/algo/assim.py +205 -151
  29. vortex/nwp/algo/clim.py +683 -517
  30. vortex/nwp/algo/coupling.py +447 -225
  31. vortex/nwp/algo/eda.py +437 -229
  32. vortex/nwp/algo/eps.py +403 -231
  33. vortex/nwp/algo/forecasts.py +416 -275
  34. vortex/nwp/algo/fpserver.py +683 -307
  35. vortex/nwp/algo/ifsnaming.py +205 -145
  36. vortex/nwp/algo/ifsroot.py +215 -122
  37. vortex/nwp/algo/monitoring.py +137 -76
  38. vortex/nwp/algo/mpitools.py +330 -190
  39. vortex/nwp/algo/odbtools.py +637 -353
  40. vortex/nwp/algo/oopsroot.py +454 -273
  41. vortex/nwp/algo/oopstests.py +90 -56
  42. vortex/nwp/algo/request.py +287 -206
  43. vortex/nwp/algo/stdpost.py +878 -522
  44. vortex/nwp/data/__init__.py +22 -4
  45. vortex/nwp/data/assim.py +125 -137
  46. vortex/nwp/data/boundaries.py +121 -68
  47. vortex/nwp/data/climfiles.py +193 -211
  48. vortex/nwp/data/configfiles.py +73 -69
  49. vortex/nwp/data/consts.py +426 -401
  50. vortex/nwp/data/ctpini.py +59 -43
  51. vortex/nwp/data/diagnostics.py +94 -66
  52. vortex/nwp/data/eda.py +50 -51
  53. vortex/nwp/data/eps.py +195 -146
  54. vortex/nwp/data/executables.py +440 -434
  55. vortex/nwp/data/fields.py +63 -48
  56. vortex/nwp/data/gridfiles.py +183 -111
  57. vortex/nwp/data/logs.py +250 -217
  58. vortex/nwp/data/modelstates.py +180 -151
  59. vortex/nwp/data/monitoring.py +72 -99
  60. vortex/nwp/data/namelists.py +254 -202
  61. vortex/nwp/data/obs.py +400 -308
  62. vortex/nwp/data/oopsexec.py +22 -20
  63. vortex/nwp/data/providers.py +90 -65
  64. vortex/nwp/data/query.py +71 -82
  65. vortex/nwp/data/stores.py +49 -36
  66. vortex/nwp/data/surfex.py +136 -137
  67. vortex/nwp/syntax/__init__.py +1 -1
  68. vortex/nwp/syntax/stdattrs.py +173 -111
  69. vortex/nwp/tools/__init__.py +2 -2
  70. vortex/nwp/tools/addons.py +22 -17
  71. vortex/nwp/tools/agt.py +24 -12
  72. vortex/nwp/tools/bdap.py +16 -5
  73. vortex/nwp/tools/bdcp.py +4 -1
  74. vortex/nwp/tools/bdm.py +3 -0
  75. vortex/nwp/tools/bdmp.py +14 -9
  76. vortex/nwp/tools/conftools.py +728 -378
  77. vortex/nwp/tools/drhook.py +12 -8
  78. vortex/nwp/tools/grib.py +65 -39
  79. vortex/nwp/tools/gribdiff.py +22 -17
  80. vortex/nwp/tools/ifstools.py +82 -42
  81. vortex/nwp/tools/igastuff.py +167 -143
  82. vortex/nwp/tools/mars.py +14 -2
  83. vortex/nwp/tools/odb.py +234 -125
  84. vortex/nwp/tools/partitioning.py +61 -37
  85. vortex/nwp/tools/satrad.py +27 -12
  86. vortex/nwp/util/async.py +83 -55
  87. vortex/nwp/util/beacon.py +10 -10
  88. vortex/nwp/util/diffpygram.py +174 -86
  89. vortex/nwp/util/ens.py +144 -63
  90. vortex/nwp/util/hooks.py +30 -19
  91. vortex/nwp/util/taskdeco.py +28 -24
  92. vortex/nwp/util/usepygram.py +278 -172
  93. vortex/nwp/util/usetnt.py +31 -17
  94. vortex/sessions.py +72 -39
  95. vortex/syntax/__init__.py +1 -1
  96. vortex/syntax/stdattrs.py +410 -171
  97. vortex/syntax/stddeco.py +31 -22
  98. vortex/toolbox.py +327 -192
  99. vortex/tools/__init__.py +11 -2
  100. vortex/tools/actions.py +110 -121
  101. vortex/tools/addons.py +111 -92
  102. vortex/tools/arm.py +42 -22
  103. vortex/tools/compression.py +72 -69
  104. vortex/tools/date.py +11 -4
  105. vortex/tools/delayedactions.py +242 -132
  106. vortex/tools/env.py +75 -47
  107. vortex/tools/folder.py +342 -171
  108. vortex/tools/grib.py +341 -162
  109. vortex/tools/lfi.py +423 -216
  110. vortex/tools/listings.py +109 -40
  111. vortex/tools/names.py +218 -156
  112. vortex/tools/net.py +655 -299
  113. vortex/tools/parallelism.py +93 -61
  114. vortex/tools/prestaging.py +55 -31
  115. vortex/tools/schedulers.py +172 -105
  116. vortex/tools/services.py +403 -334
  117. vortex/tools/storage.py +293 -358
  118. vortex/tools/surfex.py +24 -24
  119. vortex/tools/systems.py +1234 -643
  120. vortex/tools/targets.py +156 -100
  121. vortex/util/__init__.py +1 -1
  122. vortex/util/config.py +378 -327
  123. vortex/util/empty.py +2 -2
  124. vortex/util/helpers.py +56 -24
  125. vortex/util/introspection.py +18 -12
  126. vortex/util/iosponge.py +8 -4
  127. vortex/util/roles.py +4 -6
  128. vortex/util/storefunctions.py +39 -13
  129. vortex/util/structs.py +3 -3
  130. vortex/util/worker.py +29 -17
  131. vortex_nwp-2.1.0.dist-info/METADATA +67 -0
  132. vortex_nwp-2.1.0.dist-info/RECORD +144 -0
  133. {vortex_nwp-2.0.0b1.dist-info → vortex_nwp-2.1.0.dist-info}/WHEEL +1 -1
  134. vortex/layout/appconf.py +0 -109
  135. vortex/layout/jobs.py +0 -1276
  136. vortex/layout/nodes.py +0 -1424
  137. vortex/layout/subjobs.py +0 -464
  138. vortex_nwp-2.0.0b1.dist-info/METADATA +0 -50
  139. vortex_nwp-2.0.0b1.dist-info/RECORD +0 -146
  140. {vortex_nwp-2.0.0b1.dist-info → vortex_nwp-2.1.0.dist-info/licenses}/LICENSE +0 -0
  141. {vortex_nwp-2.0.0b1.dist-info → vortex_nwp-2.1.0.dist-info}/top_level.txt +0 -0
vortex/tools/listings.py CHANGED
@@ -17,7 +17,7 @@ __all__ = []
17
17
 
18
18
  def use_in_shell(sh, **kw):
19
19
  """Extend current shell with the arpifs_listings interface defined by optional arguments."""
20
- kw['shell'] = sh
20
+ kw["shell"] = sh
21
21
  return footprints.proxy.addon(**kw)
22
22
 
23
23
 
@@ -30,10 +30,10 @@ class ArpIfsListingDiff_Result:
30
30
  self._jos_diff = jos_diff
31
31
 
32
32
  def __str__(self):
33
- return '{:s} | NormsOk={:b} JoTablesOk={:b}>'.format(
34
- repr(self).rstrip('>'),
33
+ return "{:s} | NormsOk={:b} JoTablesOk={:b}>".format(
34
+ repr(self).rstrip(">"),
35
35
  all(self._norms_eq.values()),
36
- all(self._jos_eq.values())
36
+ all(self._jos_eq.values()),
37
37
  )
38
38
 
39
39
  def differences(self):
@@ -43,10 +43,24 @@ class ArpIfsListingDiff_Result:
43
43
  if all(self._norms_eq.values()):
44
44
  print("Norms check succeeded for all steps.")
45
45
  else:
46
- print("Norms check succeeded for steps:\n {:s}".format(
47
- "\n ".join([str(k) for k, v in self._norms_eq.items() if v])))
48
- print("Norms check FAILED for steps:\n {:s}".format(
49
- "\n ".join([str(k) for k, v in self._norms_eq.items() if not v])))
46
+ print(
47
+ "Norms check succeeded for steps:\n {:s}".format(
48
+ "\n ".join(
49
+ [str(k) for k, v in self._norms_eq.items() if v]
50
+ )
51
+ )
52
+ )
53
+ print(
54
+ "Norms check FAILED for steps:\n {:s}".format(
55
+ "\n ".join(
56
+ [
57
+ str(k)
58
+ for k, v in self._norms_eq.items()
59
+ if not v
60
+ ]
61
+ )
62
+ )
63
+ )
50
64
  else:
51
65
  print("No norms found in the new listing or no matching norms.")
52
66
  # print() # activation breaks test_arpifs_listings_integration.py
@@ -62,14 +76,22 @@ class ArpIfsListingDiff_Result:
62
76
  for otype_k, otype_v in todo.items():
63
77
  for sensor_k, sensor_v in otype_v.items():
64
78
  for var_k, var_v in sensor_v.items():
65
- if var_k == 'GLOBAL':
79
+ if var_k == "GLOBAL":
66
80
  continue
67
- print(" > {:s} > {:s} > {:4s} : d_n={:<9d} d_jo={:f}".format(
68
- otype_k, sensor_k, var_k,
69
- var_v['n']['diff'], var_v['jo']['diff']))
81
+ print(
82
+ " > {:s} > {:s} > {:4s} : d_n={:<9d} d_jo={:f}".format(
83
+ otype_k,
84
+ sensor_k,
85
+ var_k,
86
+ var_v["n"]["diff"],
87
+ var_v["jo"]["diff"],
88
+ )
89
+ )
70
90
  diffprinted = True
71
91
  else:
72
- print("No Jo-Tables were found or the number of Jo-Tables do not match.")
92
+ print(
93
+ "No Jo-Tables were found or the number of Jo-Tables do not match."
94
+ )
73
95
 
74
96
 
75
97
  class ArpIfsListingDiff_Status:
@@ -81,7 +103,7 @@ class ArpIfsListingDiff_Status:
81
103
  self._result = ArpIfsListingDiff_Result(norms_eq, jos_eq, jos_diff)
82
104
 
83
105
  def __str__(self):
84
- return '{:s} | rc={:b}>'.format(repr(self).rstrip('>'), bool(self))
106
+ return "{:s} | rc={:b}>".format(repr(self).rstrip(">"), bool(self))
85
107
 
86
108
  @property
87
109
  def result(self):
@@ -96,12 +118,12 @@ class ArpIfsListingsTool(addons.Addon):
96
118
  """Interface to arpifs_listings (designed as a shell Addon)."""
97
119
 
98
120
  _footprint = dict(
99
- info='Default arpifs_listings interface',
121
+ info="Default arpifs_listings interface",
100
122
  attr=dict(
101
123
  kind=dict(
102
- values=['arpifs_listings'],
124
+ values=["arpifs_listings"],
103
125
  ),
104
- )
126
+ ),
105
127
  )
106
128
 
107
129
  def arpifslist_diff(self, listing1, listing2):
@@ -147,17 +169,24 @@ class ArpIfsListingsTool(addons.Addon):
147
169
  if not l1_jos == l2_jos:
148
170
  # If the JoTables list is not consistent: do nothing
149
171
  if list(l1_jos.keys()) == list(l2_jos.keys()):
150
- for table1, table2 in zip(l1_jos.values(), l2_jos.values()):
172
+ for table1, table2 in zip(
173
+ l1_jos.values(), l2_jos.values()
174
+ ):
151
175
  jos_eq[table1.name] = table1 == table2
152
176
  if not jos_eq[table1.name]:
153
177
  jos_diff[table1.name] = OrderedDict()
154
178
  # We only save differences when deltaN or deltaJo != 0
155
- for otype_k, otype_v in table2.compute_diff(table1).items():
179
+ for otype_k, otype_v in table2.compute_diff(
180
+ table1
181
+ ).items():
156
182
  otype_tmp = OrderedDict()
157
183
  for sensor_k, sensor_v in otype_v.items():
158
184
  sensor_tmp = OrderedDict()
159
185
  for k, v in sensor_v.items():
160
- if v['n']['diff'] != 0 or v['jo']['diff'] != 0:
186
+ if (
187
+ v["n"]["diff"] != 0
188
+ or v["jo"]["diff"] != 0
189
+ ):
161
190
  sensor_tmp[k] = v
162
191
  if len(sensor_tmp):
163
192
  otype_tmp[sensor_k] = sensor_tmp
@@ -174,7 +203,9 @@ class ArpifsListingsFormatAdapter(FormatAdapterAbstractImplementation):
174
203
  _footprint = dict(
175
204
  attr=dict(
176
205
  format=dict(
177
- values=['ARPIFSLIST', ],
206
+ values=[
207
+ "ARPIFSLIST",
208
+ ],
178
209
  ),
179
210
  )
180
211
  )
@@ -196,8 +227,15 @@ class ArpifsListingsFormatAdapter(FormatAdapterAbstractImplementation):
196
227
  def lines(self):
197
228
  """Return an array populated with the listing file lines."""
198
229
  if self._lines is None:
199
- with open(self.filename, self.openmode, encoding='utf-8', errors='replace') as f:
200
- self._lines = [l.rstrip("\n") for l in f] # to remove trailing '\n'
230
+ with open(
231
+ self.filename,
232
+ self.openmode,
233
+ encoding="utf-8",
234
+ errors="replace",
235
+ ) as f:
236
+ self._lines = [
237
+ l.rstrip("\n") for l in f
238
+ ] # to remove trailing '\n'
201
239
  return self._lines
202
240
 
203
241
  def flush_lines(self):
@@ -210,7 +248,14 @@ class ArpifsListingsFormatAdapter(FormatAdapterAbstractImplementation):
210
248
  if self._end_is_reached is None:
211
249
  self._end_is_reached = False
212
250
  for line in self.lines:
213
- if any([p in line for p in listings.OutputListing.patterns['end_is_reached']]):
251
+ if any(
252
+ [
253
+ p in line
254
+ for p in listings.OutputListing.patterns[
255
+ "end_is_reached"
256
+ ]
257
+ ]
258
+ ):
214
259
  self._end_is_reached = True
215
260
  break
216
261
  return self._end_is_reached
@@ -237,7 +282,9 @@ class ArpifsListingsFormatAdapter(FormatAdapterAbstractImplementation):
237
282
  def cost_functions(self):
238
283
  """Return a :class:`arpifs_listings.jo_tables.JoTables` object."""
239
284
  if self._costs is None:
240
- self._costs = cost_functions.CostFunctions(self.filename, self.lines)
285
+ self._costs = cost_functions.CostFunctions(
286
+ self.filename, self.lines
287
+ )
241
288
  if not self.fmtdelayedopen:
242
289
  self.flush_lines()
243
290
  return self._costs
@@ -266,12 +313,15 @@ class ListBasedCutoffDispenser:
266
313
  if f_dates:
267
314
  f_cutoffs[k] = f_dates
268
315
  if f_cutoffs:
269
- self._max_cutoff = max([max(dates) for dates in f_cutoffs.values()])
316
+ self._max_cutoff = max(
317
+ [max(dates) for dates in f_cutoffs.values()]
318
+ )
270
319
  else:
271
320
  self._max_cutoff = None
272
321
  self._default_cutoffs = defaultdict(lambda: self._max_cutoff)
273
- self._default_cutoffs.update({k: max(dates)
274
- for k, dates in f_cutoffs.items()})
322
+ self._default_cutoffs.update(
323
+ {k: max(dates) for k, dates in f_cutoffs.items()}
324
+ )
275
325
  self._fuse_per_obstype = fuse_per_obstype
276
326
 
277
327
  @property
@@ -300,15 +350,21 @@ class BdmBufrListingsFormatAdapter(FormatAdapterAbstractImplementation):
300
350
  _footprint = dict(
301
351
  attr=dict(
302
352
  format=dict(
303
- values=['BDMBUFR_LISTING', ],
353
+ values=[
354
+ "BDMBUFR_LISTING",
355
+ ],
304
356
  ),
305
357
  )
306
358
  )
307
359
 
308
- _RE_OBSTYPE_GRP = re.compile(r"^.*tentative\s+(?:d')?extraction\s+pour\s+'?(?P<obstype>\w+)'?\b",
309
- re.IGNORECASE)
310
- _RE_OBSTYPE_CUT = re.compile(r"^.*cutoff\s+pour\s+'?(?P<obstype>\w+)'?\s*:\s*(?P<datetime>\d+)\b",
311
- re.IGNORECASE)
360
+ _RE_OBSTYPE_GRP = re.compile(
361
+ r"^.*tentative\s+(?:d')?extraction\s+pour\s+'?(?P<obstype>\w+)'?\b",
362
+ re.IGNORECASE,
363
+ )
364
+ _RE_OBSTYPE_CUT = re.compile(
365
+ r"^.*cutoff\s+pour\s+'?(?P<obstype>\w+)'?\s*:\s*(?P<datetime>\d+)\b",
366
+ re.IGNORECASE,
367
+ )
312
368
 
313
369
  def __init__(self, *kargs, **kwargs):
314
370
  super().__init__(*kargs, **kwargs)
@@ -321,8 +377,15 @@ class BdmBufrListingsFormatAdapter(FormatAdapterAbstractImplementation):
321
377
  def lines(self):
322
378
  """Return an array populated with the listing file lines."""
323
379
  if self._lines is None:
324
- with open(self.filename, self.openmode, encoding='utf-8', errors='replace') as f:
325
- self._lines = [l.rstrip("\n") for l in f] # to remove trailing '\n'
380
+ with open(
381
+ self.filename,
382
+ self.openmode,
383
+ encoding="utf-8",
384
+ errors="replace",
385
+ ) as f:
386
+ self._lines = [
387
+ l.rstrip("\n") for l in f
388
+ ] # to remove trailing '\n'
326
389
  return self._lines
327
390
 
328
391
  @property
@@ -338,11 +401,16 @@ class BdmBufrListingsFormatAdapter(FormatAdapterAbstractImplementation):
338
401
  if l_match:
339
402
  if cur_obstype is not None:
340
403
  self._cutoffs[cur_obstype].append(None)
341
- cur_obstype = l_match.group('obstype').lower()
404
+ cur_obstype = l_match.group("obstype").lower()
342
405
  if cur_obstype:
343
406
  l_match = self._RE_OBSTYPE_CUT.match(line)
344
- if l_match and l_match.group('obstype').lower() == cur_obstype:
345
- self._cutoffs[cur_obstype].append(Date(l_match.group('datetime')))
407
+ if (
408
+ l_match
409
+ and l_match.group("obstype").lower() == cur_obstype
410
+ ):
411
+ self._cutoffs[cur_obstype].append(
412
+ Date(l_match.group("datetime"))
413
+ )
346
414
  cur_obstype = None
347
415
  if cur_obstype is not None:
348
416
  self._cutoffs[cur_obstype].append(None)
@@ -350,5 +418,6 @@ class BdmBufrListingsFormatAdapter(FormatAdapterAbstractImplementation):
350
418
 
351
419
  def cutoffs_dispenser(self, fuse_per_obstype=False):
352
420
  """Return a new :class:`CutoffDispenser` object."""
353
- return ListBasedCutoffDispenser(copy.deepcopy(self.cutoffs),
354
- fuse_per_obstype=fuse_per_obstype)
421
+ return ListBasedCutoffDispenser(
422
+ copy.deepcopy(self.cutoffs), fuse_per_obstype=fuse_per_obstype
423
+ )