vortex-nwp 2.0.0b1__py3-none-any.whl → 2.0.0b2__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 (139) hide show
  1. vortex/__init__.py +59 -45
  2. vortex/algo/__init__.py +3 -2
  3. vortex/algo/components.py +940 -614
  4. vortex/algo/mpitools.py +802 -497
  5. vortex/algo/serversynctools.py +34 -33
  6. vortex/config.py +19 -22
  7. vortex/data/__init__.py +9 -3
  8. vortex/data/abstractstores.py +593 -655
  9. vortex/data/containers.py +217 -162
  10. vortex/data/contents.py +65 -39
  11. vortex/data/executables.py +93 -102
  12. vortex/data/flow.py +40 -34
  13. vortex/data/geometries.py +228 -132
  14. vortex/data/handlers.py +428 -225
  15. vortex/data/outflow.py +15 -15
  16. vortex/data/providers.py +185 -163
  17. vortex/data/resources.py +48 -42
  18. vortex/data/stores.py +544 -413
  19. vortex/gloves.py +114 -87
  20. vortex/layout/__init__.py +1 -8
  21. vortex/layout/contexts.py +150 -84
  22. vortex/layout/dataflow.py +353 -202
  23. vortex/layout/monitor.py +264 -128
  24. vortex/nwp/__init__.py +5 -2
  25. vortex/nwp/algo/__init__.py +14 -5
  26. vortex/nwp/algo/assim.py +205 -151
  27. vortex/nwp/algo/clim.py +683 -517
  28. vortex/nwp/algo/coupling.py +447 -225
  29. vortex/nwp/algo/eda.py +437 -229
  30. vortex/nwp/algo/eps.py +403 -231
  31. vortex/nwp/algo/forecasts.py +420 -271
  32. vortex/nwp/algo/fpserver.py +683 -307
  33. vortex/nwp/algo/ifsnaming.py +205 -145
  34. vortex/nwp/algo/ifsroot.py +210 -122
  35. vortex/nwp/algo/monitoring.py +132 -76
  36. vortex/nwp/algo/mpitools.py +321 -191
  37. vortex/nwp/algo/odbtools.py +617 -353
  38. vortex/nwp/algo/oopsroot.py +449 -273
  39. vortex/nwp/algo/oopstests.py +90 -56
  40. vortex/nwp/algo/request.py +287 -206
  41. vortex/nwp/algo/stdpost.py +878 -522
  42. vortex/nwp/data/__init__.py +22 -4
  43. vortex/nwp/data/assim.py +125 -137
  44. vortex/nwp/data/boundaries.py +121 -68
  45. vortex/nwp/data/climfiles.py +193 -211
  46. vortex/nwp/data/configfiles.py +73 -69
  47. vortex/nwp/data/consts.py +426 -401
  48. vortex/nwp/data/ctpini.py +59 -43
  49. vortex/nwp/data/diagnostics.py +94 -66
  50. vortex/nwp/data/eda.py +50 -51
  51. vortex/nwp/data/eps.py +195 -146
  52. vortex/nwp/data/executables.py +440 -434
  53. vortex/nwp/data/fields.py +63 -48
  54. vortex/nwp/data/gridfiles.py +183 -111
  55. vortex/nwp/data/logs.py +250 -217
  56. vortex/nwp/data/modelstates.py +180 -151
  57. vortex/nwp/data/monitoring.py +72 -99
  58. vortex/nwp/data/namelists.py +254 -202
  59. vortex/nwp/data/obs.py +400 -308
  60. vortex/nwp/data/oopsexec.py +22 -20
  61. vortex/nwp/data/providers.py +90 -65
  62. vortex/nwp/data/query.py +71 -82
  63. vortex/nwp/data/stores.py +49 -36
  64. vortex/nwp/data/surfex.py +136 -137
  65. vortex/nwp/syntax/__init__.py +1 -1
  66. vortex/nwp/syntax/stdattrs.py +173 -111
  67. vortex/nwp/tools/__init__.py +2 -2
  68. vortex/nwp/tools/addons.py +22 -17
  69. vortex/nwp/tools/agt.py +24 -12
  70. vortex/nwp/tools/bdap.py +16 -5
  71. vortex/nwp/tools/bdcp.py +4 -1
  72. vortex/nwp/tools/bdm.py +3 -0
  73. vortex/nwp/tools/bdmp.py +14 -9
  74. vortex/nwp/tools/conftools.py +728 -378
  75. vortex/nwp/tools/drhook.py +12 -8
  76. vortex/nwp/tools/grib.py +65 -39
  77. vortex/nwp/tools/gribdiff.py +22 -17
  78. vortex/nwp/tools/ifstools.py +82 -42
  79. vortex/nwp/tools/igastuff.py +167 -143
  80. vortex/nwp/tools/mars.py +14 -2
  81. vortex/nwp/tools/odb.py +234 -125
  82. vortex/nwp/tools/partitioning.py +61 -37
  83. vortex/nwp/tools/satrad.py +27 -12
  84. vortex/nwp/util/async.py +83 -55
  85. vortex/nwp/util/beacon.py +10 -10
  86. vortex/nwp/util/diffpygram.py +174 -86
  87. vortex/nwp/util/ens.py +144 -63
  88. vortex/nwp/util/hooks.py +30 -19
  89. vortex/nwp/util/taskdeco.py +28 -24
  90. vortex/nwp/util/usepygram.py +278 -172
  91. vortex/nwp/util/usetnt.py +31 -17
  92. vortex/sessions.py +72 -39
  93. vortex/syntax/__init__.py +1 -1
  94. vortex/syntax/stdattrs.py +410 -171
  95. vortex/syntax/stddeco.py +31 -22
  96. vortex/toolbox.py +327 -192
  97. vortex/tools/__init__.py +11 -2
  98. vortex/tools/actions.py +125 -59
  99. vortex/tools/addons.py +111 -92
  100. vortex/tools/arm.py +42 -22
  101. vortex/tools/compression.py +72 -69
  102. vortex/tools/date.py +11 -4
  103. vortex/tools/delayedactions.py +242 -132
  104. vortex/tools/env.py +75 -47
  105. vortex/tools/folder.py +342 -171
  106. vortex/tools/grib.py +311 -149
  107. vortex/tools/lfi.py +423 -216
  108. vortex/tools/listings.py +109 -40
  109. vortex/tools/names.py +218 -156
  110. vortex/tools/net.py +632 -298
  111. vortex/tools/parallelism.py +93 -61
  112. vortex/tools/prestaging.py +55 -31
  113. vortex/tools/schedulers.py +172 -105
  114. vortex/tools/services.py +402 -333
  115. vortex/tools/storage.py +293 -358
  116. vortex/tools/surfex.py +24 -24
  117. vortex/tools/systems.py +1211 -631
  118. vortex/tools/targets.py +156 -100
  119. vortex/util/__init__.py +1 -1
  120. vortex/util/config.py +377 -327
  121. vortex/util/empty.py +2 -2
  122. vortex/util/helpers.py +56 -24
  123. vortex/util/introspection.py +18 -12
  124. vortex/util/iosponge.py +8 -4
  125. vortex/util/roles.py +4 -6
  126. vortex/util/storefunctions.py +39 -13
  127. vortex/util/structs.py +3 -3
  128. vortex/util/worker.py +29 -17
  129. vortex_nwp-2.0.0b2.dist-info/METADATA +66 -0
  130. vortex_nwp-2.0.0b2.dist-info/RECORD +142 -0
  131. {vortex_nwp-2.0.0b1.dist-info → vortex_nwp-2.0.0b2.dist-info}/WHEEL +1 -1
  132. vortex/layout/appconf.py +0 -109
  133. vortex/layout/jobs.py +0 -1276
  134. vortex/layout/nodes.py +0 -1424
  135. vortex/layout/subjobs.py +0 -464
  136. vortex_nwp-2.0.0b1.dist-info/METADATA +0 -50
  137. vortex_nwp-2.0.0b1.dist-info/RECORD +0 -146
  138. {vortex_nwp-2.0.0b1.dist-info → vortex_nwp-2.0.0b2.dist-info}/LICENSE +0 -0
  139. {vortex_nwp-2.0.0b1.dist-info → vortex_nwp-2.0.0b2.dist-info}/top_level.txt +0 -0
vortex/syntax/stdattrs.py CHANGED
@@ -13,46 +13,159 @@ from bronx.syntax.decorators import secure_getattr
13
13
  from bronx.system import hash as hashutils
14
14
  from vortex.tools import env
15
15
 
16
- from .stddeco import generic_pathname_insert, namebuilding_append, namebuilding_insert
16
+ from .stddeco import (
17
+ generic_pathname_insert,
18
+ namebuilding_append,
19
+ namebuilding_insert,
20
+ )
17
21
 
18
22
  #: Export a set of attributes :data:`a_model`, :data:`a_date`, etc..
19
23
  __all__ = [
20
- 'a_xpid', 'a_month', 'a_domain', 'a_truncation', 'a_model', 'a_member',
21
- 'a_date', 'a_cutoff', 'a_term', 'a_nativefmt', 'a_actualfmt', 'a_suite',
22
- 'a_namespace', 'a_hashalgo', 'a_compressionpipeline', 'a_block', 'a_number'
24
+ "a_xpid",
25
+ "a_month",
26
+ "a_domain",
27
+ "a_truncation",
28
+ "a_model",
29
+ "a_member",
30
+ "a_date",
31
+ "a_cutoff",
32
+ "a_term",
33
+ "a_nativefmt",
34
+ "a_actualfmt",
35
+ "a_suite",
36
+ "a_namespace",
37
+ "a_hashalgo",
38
+ "a_compressionpipeline",
39
+ "a_block",
40
+ "a_number",
23
41
  ]
24
42
 
25
43
  #: Possible values for the *model* attribute.
26
44
  models = {
27
- 'arpege', 'arp', 'arp_court', 'aladin', 'ald', 'arome', 'aro', 'aearp', 'pearp', 'mocage',
28
- 'mesonh', 'surfex', 'hycom', 'psy4', 'mercator_global', 'glo12', 'safran', 'ifs', 'aroifs', 'cifs',
29
- 'mfwam', 'pg1', 'alpha', 'eps', 'postproc', 'ww3', 'sympo', 'psym', 'petaroute', 'promethee',
30
- 'hycom3d', 'croco', 'alaro', 'harmoniearome', 'nemo', 'oasis',
45
+ "arpege",
46
+ "arp",
47
+ "arp_court",
48
+ "aladin",
49
+ "ald",
50
+ "arome",
51
+ "aro",
52
+ "aearp",
53
+ "pearp",
54
+ "mocage",
55
+ "mesonh",
56
+ "surfex",
57
+ "hycom",
58
+ "psy4",
59
+ "mercator_global",
60
+ "glo12",
61
+ "safran",
62
+ "ifs",
63
+ "aroifs",
64
+ "cifs",
65
+ "mfwam",
66
+ "pg1",
67
+ "alpha",
68
+ "eps",
69
+ "postproc",
70
+ "ww3",
71
+ "sympo",
72
+ "psym",
73
+ "petaroute",
74
+ "promethee",
75
+ "hycom3d",
76
+ "croco",
77
+ "alaro",
78
+ "harmoniearome",
79
+ "nemo",
80
+ "oasis",
31
81
  }
32
82
 
33
83
  #: Possible values for the most common binaries.
34
84
  binaries = {
35
- 'arpege', 'aladin', 'arome', 'aromeom_common', 'batodb', 'peace', 'mocage', 'sumo',
36
- 'corromegasurf', 'mesonh', 'safran', 'surfex', 'macc', 'mktopbd', 'ifs', 'oops',
37
- 'assistance', 'arpifs', 'mfwam', 'mfwam_interp', 'mfwam_interpbc', 'ww3', 'ww3_prnc',
38
- 'ww3_bound', 'ww3_ncgrb', 'ial', 'alaro', 'harmoniearome', 'nemo', 'oasis', 'arobase',
39
- 'xios',
85
+ "arpege",
86
+ "aladin",
87
+ "arome",
88
+ "aromeom_common",
89
+ "batodb",
90
+ "peace",
91
+ "mocage",
92
+ "sumo",
93
+ "corromegasurf",
94
+ "mesonh",
95
+ "safran",
96
+ "surfex",
97
+ "macc",
98
+ "mktopbd",
99
+ "ifs",
100
+ "oops",
101
+ "assistance",
102
+ "arpifs",
103
+ "mfwam",
104
+ "mfwam_interp",
105
+ "mfwam_interpbc",
106
+ "ww3",
107
+ "ww3_prnc",
108
+ "ww3_bound",
109
+ "ww3_ncgrb",
110
+ "ial",
111
+ "alaro",
112
+ "harmoniearome",
113
+ "nemo",
114
+ "oasis",
115
+ "arobase",
116
+ "xios",
40
117
  }
41
118
 
42
119
  #: Possible values for the most common utility programs.
43
- utilities = {'batodb'}
120
+ utilities = {"batodb"}
44
121
 
45
122
  #: Known formats
46
123
  knownfmt = {
47
- 'auto', 'autoconfig', 'unknown', 'foo', 'arpifslist', 'bdmbufr_listing', 'ascii', 'txt',
48
- 'json', 'fa', 'lfi', 'lfa', 'netcdf', 'grib', 'grib1', 'grib2', 'bufr', 'hdf5', 'obsoul',
49
- 'odb', 'ecma', 'ccma', 'bullx', 'sx', 'ddhpack', 'tar', 'tgz', 'rawfiles', 'binary', 'bin',
50
- 'obslocationpack', 'obsfirepack', 'wbcpack', 'geo', 'nam', 'png', 'pdf', 'dir/hdr', 'yml',
51
- 'yaml', 'ini'
124
+ "auto",
125
+ "autoconfig",
126
+ "unknown",
127
+ "foo",
128
+ "arpifslist",
129
+ "bdmbufr_listing",
130
+ "ascii",
131
+ "txt",
132
+ "json",
133
+ "fa",
134
+ "lfi",
135
+ "lfa",
136
+ "netcdf",
137
+ "grib",
138
+ "grib1",
139
+ "grib2",
140
+ "bufr",
141
+ "hdf5",
142
+ "obsoul",
143
+ "odb",
144
+ "ecma",
145
+ "ccma",
146
+ "bullx",
147
+ "sx",
148
+ "ddhpack",
149
+ "tar",
150
+ "tgz",
151
+ "rawfiles",
152
+ "binary",
153
+ "bin",
154
+ "obslocationpack",
155
+ "obsfirepack",
156
+ "wbcpack",
157
+ "geo",
158
+ "nam",
159
+ "png",
160
+ "pdf",
161
+ "dir/hdr",
162
+ "yml",
163
+ "yaml",
164
+ "ini",
52
165
  }
53
166
 
54
167
  #: Default attributes excluded from `repr` display
55
- notinrepr = {'kind', 'unknown', 'clscontents', 'gvar', 'nativefmt'}
168
+ notinrepr = {"kind", "unknown", "clscontents", "gvar", "nativefmt"}
56
169
 
57
170
 
58
171
  class DelayedEnvValue:
@@ -69,7 +182,7 @@ class DelayedEnvValue:
69
182
  self._frozen = False
70
183
 
71
184
  def as_dump(self):
72
- return 'varname={},default={}'.format(self.varname, self.default)
185
+ return "varname={},default={}".format(self.varname, self.default)
73
186
 
74
187
  def footprint_value(self):
75
188
  """
@@ -104,10 +217,13 @@ class DelayedInit:
104
217
  return getattr(self.__proxied, name)
105
218
 
106
219
  def __repr__(self):
107
- orig = re.sub('^<(.*)>$', r'\1', super().__repr__())
108
- return '<{:s} | proxied={:s}>'.format(orig,
109
- 'Not yet Initialised' if self.__proxied is None
110
- else repr(self.__proxied))
220
+ orig = re.sub("^<(.*)>$", r"\1", super().__repr__())
221
+ return "<{:s} | proxied={:s}>".format(
222
+ orig,
223
+ "Not yet Initialised"
224
+ if self.__proxied is None
225
+ else repr(self.__proxied),
226
+ )
111
227
 
112
228
  def __str__(self):
113
229
  return repr(self) if self.__proxied is None else str(self.__proxied)
@@ -116,13 +232,13 @@ class DelayedInit:
116
232
  class FmtInt(int):
117
233
  """Formated integer."""
118
234
 
119
- def __new__(cls, value, fmt='02'):
235
+ def __new__(cls, value, fmt="02"):
120
236
  obj = int.__new__(cls, value)
121
237
  obj._fmt = fmt
122
238
  return obj
123
239
 
124
240
  def __str__(self):
125
- return '{0:{fmt}d}'.format(self.__int__(), fmt=self._fmt)
241
+ return "{0:{fmt}d}".format(self.__int__(), fmt=self._fmt)
126
242
 
127
243
  def export_dict(self):
128
244
  """The pure dict/json output is the raw integer"""
@@ -130,11 +246,12 @@ class FmtInt(int):
130
246
 
131
247
  def nice(self, value):
132
248
  """Returns the specified ``value`` with the format of the current object."""
133
- return '{0:{fmt}d}'.format(value, fmt=self._fmt)
249
+ return "{0:{fmt}d}".format(value, fmt=self._fmt)
134
250
 
135
251
 
136
252
  class XPid(str):
137
253
  """Basestring wrapper for experiment ids (abstract)."""
254
+
138
255
  pass
139
256
 
140
257
 
@@ -142,8 +259,8 @@ class LegacyXPid(XPid):
142
259
  """Basestring wrapper for experiment ids (Olive/Oper convention)."""
143
260
 
144
261
  def __new__(cls, value):
145
- if len(value) != 4 or '@' in value:
146
- raise ValueError('XPid should be a 4 digits string')
262
+ if len(value) != 4 or "@" in value:
263
+ raise ValueError("XPid should be a 4 digits string")
147
264
  return str.__new__(cls, value.upper())
148
265
 
149
266
  def isoper(self):
@@ -154,21 +271,24 @@ class LegacyXPid(XPid):
154
271
  class FreeXPid(XPid):
155
272
  """Basestring wrapper for experiment ids (User defined)."""
156
273
 
157
- _re_valid = re.compile(r'^\S+@[-\w]+$')
274
+ _re_valid = re.compile(r"^\S+@[-\w]+$")
158
275
 
159
276
  def __new__(cls, value):
160
277
  if not cls._re_valid.match(value):
161
- raise ValueError('XPid should be something like "id@location" (not "{:s}")'
162
- .format(value))
278
+ raise ValueError(
279
+ 'XPid should be something like "id@location" (not "{:s}")'.format(
280
+ value
281
+ )
282
+ )
163
283
  return str.__new__(cls, value)
164
284
 
165
285
  @property
166
286
  def id(self):
167
- return self.split('@')[0]
287
+ return self.split("@")[0]
168
288
 
169
289
  @property
170
290
  def location(self):
171
- return self.split('@')[1]
291
+ return self.split("@")[1]
172
292
 
173
293
 
174
294
  def any_vortex_xpid(xpidguess):
@@ -179,16 +299,23 @@ def any_vortex_xpid(xpidguess):
179
299
  except ValueError:
180
300
  xp = FreeXPid(xpidguess)
181
301
  except ValueError:
182
- raise ValueError("'{:s}' could not be reclassed as a LegacyXPid or a FreeXPid")
302
+ raise ValueError(
303
+ "'{:s}' could not be reclassed as a LegacyXPid or a FreeXPid"
304
+ )
183
305
  return xp
184
306
 
185
307
 
186
308
  #: The list of operational experiment names.
187
- opsuites = {LegacyXPid(x) for x in (['OPER', 'DBLE', 'TEST', 'MIRR'] +
188
- ['OP{:02d}'.format(i) for i in range(100)])}
309
+ opsuites = {
310
+ LegacyXPid(x)
311
+ for x in (
312
+ ["OPER", "DBLE", "TEST", "MIRR"]
313
+ + ["OP{:02d}".format(i) for i in range(100)]
314
+ )
315
+ }
189
316
 
190
317
  #: The list of experiemnt names dedicated to Vortex' demos
191
- demosuites = {LegacyXPid('DEMO'), LegacyXPid('DREF')}
318
+ demosuites = {LegacyXPid("DEMO"), LegacyXPid("DREF")}
192
319
 
193
320
 
194
321
  class Namespace(str):
@@ -197,20 +324,22 @@ class Namespace(str):
197
324
  def __new__(cls, value):
198
325
  value = value.lower()
199
326
  full = value
200
- if '@' in value:
201
- netuser, value = value.split('@')
202
- if ':' in netuser:
203
- netuser, netpass = netuser.split(':')
327
+ if "@" in value:
328
+ netuser, value = value.split("@")
329
+ if ":" in netuser:
330
+ netuser, netpass = netuser.split(":")
204
331
  else:
205
332
  netpass = None
206
333
  else:
207
334
  netuser, netpass = None, None
208
- if ':' in value:
209
- value, port = value.split(':')
335
+ if ":" in value:
336
+ value, port = value.split(":")
210
337
  else:
211
338
  port = None
212
- if 0 < value.count('.') < 2:
213
- raise ValueError('Namespace should contain one or at least 3 fields')
339
+ if 0 < value.count(".") < 2:
340
+ raise ValueError(
341
+ "Namespace should contain one or at least 3 fields"
342
+ )
214
343
  thisns = str.__new__(cls, value)
215
344
  thisns._port = int(port) if port else None
216
345
  thisns._user = netuser
@@ -220,12 +349,12 @@ class Namespace(str):
220
349
 
221
350
  @property
222
351
  def firstname(self):
223
- return self.split('.', 1)[0]
352
+ return self.split(".", 1)[0]
224
353
 
225
354
  @property
226
355
  def domain(self):
227
- if '.' in self.netloc:
228
- return self.split('.', 1)[1]
356
+ if "." in self.netloc:
357
+ return self.split(".", 1)[1]
229
358
  else:
230
359
  return self.netloc
231
360
 
@@ -251,23 +380,23 @@ class Latitude(float):
251
380
 
252
381
  def __new__(cls, value):
253
382
  value = str(value).lower()
254
- if value.endswith('n'):
383
+ if value.endswith("n"):
255
384
  value = value[:-1]
256
- elif value.endswith('s'):
385
+ elif value.endswith("s"):
257
386
  value = value[:-1]
258
- if not value.startswith('-'):
259
- value = '-' + value
387
+ if not value.startswith("-"):
388
+ value = "-" + value
260
389
  if not -90 <= float(value) <= 90:
261
- raise ValueError('Latitude out of bounds: ' + value)
390
+ raise ValueError("Latitude out of bounds: " + value)
262
391
  return float.__new__(cls, value)
263
392
 
264
393
  def nice(self):
265
- ns = 'N' if self >= 0 else 'S'
266
- return str(self).strip('-') + ns
394
+ ns = "N" if self >= 0 else "S"
395
+ return str(self).strip("-") + ns
267
396
 
268
397
  @property
269
398
  def hemisphere(self):
270
- return 'North' if self >= 0 else 'South'
399
+ return "North" if self >= 0 else "South"
271
400
 
272
401
 
273
402
  class Longitude(float):
@@ -275,23 +404,23 @@ class Longitude(float):
275
404
 
276
405
  def __new__(cls, value):
277
406
  value = str(value).lower()
278
- if value.endswith('e'):
407
+ if value.endswith("e"):
279
408
  value = value[:-1]
280
- elif value.endswith('w'):
409
+ elif value.endswith("w"):
281
410
  value = value[:-1]
282
- if not value.startswith('-'):
283
- value = '-' + value
411
+ if not value.startswith("-"):
412
+ value = "-" + value
284
413
  if not -180 <= float(value) <= 180:
285
- raise ValueError('Longitude out of bounds: ' + value)
414
+ raise ValueError("Longitude out of bounds: " + value)
286
415
  return float.__new__(cls, value)
287
416
 
288
417
  def nice(self):
289
- ns = 'E' if self >= 0 else 'W'
290
- return str(self).strip('-') + ns
418
+ ns = "E" if self >= 0 else "W"
419
+ return str(self).strip("-") + ns
291
420
 
292
421
  @property
293
422
  def hemisphere(self):
294
- return 'East' if self >= 0 else 'West'
423
+ return "East" if self >= 0 else "West"
295
424
 
296
425
 
297
426
  # predefined attributes
@@ -303,46 +432,52 @@ a_xpid = dict(
303
432
  optional=False,
304
433
  )
305
434
 
306
- xpid = footprints.Footprint(info='Abstract experiment id',
307
- attr=dict(experiment=a_xpid))
435
+ xpid = footprints.Footprint(
436
+ info="Abstract experiment id", attr=dict(experiment=a_xpid)
437
+ )
308
438
 
309
439
  #: Usual definition for an Olive/Oper ``xpid`` (*e.g.* experiment name).
310
440
  a_legacy_xpid = copy.copy(a_xpid)
311
- a_legacy_xpid['type'] = LegacyXPid
441
+ a_legacy_xpid["type"] = LegacyXPid
312
442
 
313
- legacy_xpid = footprints.Footprint(info='Abstract experiment id',
314
- attr=dict(experiment=a_legacy_xpid))
443
+ legacy_xpid = footprints.Footprint(
444
+ info="Abstract experiment id", attr=dict(experiment=a_legacy_xpid)
445
+ )
315
446
 
316
447
  #: Usual definition for a user-defined ``xpid`` (*e.g.* experiment name).
317
448
  a_free_xpid = copy.copy(a_xpid)
318
- a_free_xpid['type'] = FreeXPid
449
+ a_free_xpid["type"] = FreeXPid
319
450
 
320
- free_xpid = footprints.Footprint(info='Abstract experiment id',
321
- attr=dict(experiment=a_free_xpid))
451
+ free_xpid = footprints.Footprint(
452
+ info="Abstract experiment id", attr=dict(experiment=a_free_xpid)
453
+ )
322
454
 
323
455
  #: Usual definition of the ``nativefmt`` attribute.
324
456
  a_nativefmt = dict(
325
457
  info="The resource's storage format.",
326
458
  optional=True,
327
- default='foo',
459
+ default="foo",
328
460
  values=knownfmt,
329
- remap=dict(auto='foo'),
461
+ remap=dict(auto="foo"),
330
462
  )
331
463
 
332
- nativefmt = footprints.Footprint(info='Native format', attr=dict(nativefmt=a_nativefmt))
464
+ nativefmt = footprints.Footprint(
465
+ info="Native format", attr=dict(nativefmt=a_nativefmt)
466
+ )
333
467
 
334
468
 
335
469
  def _namebuilding_insert_nativefmt(cls):
336
-
337
- if hasattr(cls, 'namebuilding_info'):
470
+ if hasattr(cls, "namebuilding_info"):
338
471
  original_namebuilding_info = cls.namebuilding_info
339
472
 
340
473
  def namebuilding_info(self):
341
474
  vinfo = original_namebuilding_info(self)
342
- ext_remap = getattr(self, '_extension_remap', dict())
475
+ ext_remap = getattr(self, "_extension_remap", dict())
343
476
  ext_value = ext_remap.get(self.nativefmt, self.nativefmt)
344
477
  if ext_value is not None:
345
- vinfo.setdefault('fmt', ext_remap.get(self.nativefmt, self.nativefmt))
478
+ vinfo.setdefault(
479
+ "fmt", ext_remap.get(self.nativefmt, self.nativefmt)
480
+ )
346
481
  return vinfo
347
482
 
348
483
  namebuilding_info.__doc__ = original_namebuilding_info.__doc__
@@ -353,67 +488,97 @@ def _namebuilding_insert_nativefmt(cls):
353
488
 
354
489
  nativefmt_deco = footprints.DecorativeFootprint(
355
490
  nativefmt,
356
- decorator=[_namebuilding_insert_nativefmt,
357
- generic_pathname_insert('nativefmt', lambda self: self.nativefmt, setdefault=True)])
491
+ decorator=[
492
+ _namebuilding_insert_nativefmt,
493
+ generic_pathname_insert(
494
+ "nativefmt", lambda self: self.nativefmt, setdefault=True
495
+ ),
496
+ ],
497
+ )
358
498
 
359
499
  #: Usual definition of the ``actualfmt`` attribute.
360
500
  a_actualfmt = dict(
361
501
  info="The resource's format.",
362
502
  optional=True,
363
- default='[nativefmt#unknown]',
364
- alias=('format',),
503
+ default="[nativefmt#unknown]",
504
+ alias=("format",),
365
505
  values=knownfmt,
366
- remap=dict(auto='foo'),
506
+ remap=dict(auto="foo"),
367
507
  )
368
508
 
369
- actualfmt = footprints.Footprint(info='Actual data format', attr=dict(actualfmt=a_actualfmt))
509
+ actualfmt = footprints.Footprint(
510
+ info="Actual data format", attr=dict(actualfmt=a_actualfmt)
511
+ )
370
512
 
371
513
  #: Usual definition of the ``cutoff`` attribute.
372
514
  a_cutoff = dict(
373
515
  info="The cutoff type of the generating process.",
374
516
  optional=False,
375
- alias=('cut',),
517
+ alias=("cut",),
376
518
  values=[
377
- 'a', 'assim', 'assimilation', 'long',
378
- 'p', 'prod', 'production', 'short'
519
+ "a",
520
+ "assim",
521
+ "assimilation",
522
+ "long",
523
+ "p",
524
+ "prod",
525
+ "production",
526
+ "short",
379
527
  ],
380
528
  remap=dict(
381
- a='assim',
382
- p='production',
383
- prod='production',
384
- long='assim',
385
- assimilation='assim'
386
- )
529
+ a="assim",
530
+ p="production",
531
+ prod="production",
532
+ long="assim",
533
+ assimilation="assim",
534
+ ),
387
535
  )
388
536
 
389
- cutoff = footprints.Footprint(info='Abstract cutoff', attr=dict(cutoff=a_cutoff))
537
+ cutoff = footprints.Footprint(
538
+ info="Abstract cutoff", attr=dict(cutoff=a_cutoff)
539
+ )
390
540
 
391
541
  cutoff_deco = footprints.DecorativeFootprint(
392
542
  cutoff,
393
- decorator=[namebuilding_append('flow',
394
- lambda self: None if self.cutoff is None else {'shortcutoff': self.cutoff},
395
- none_discard=True),
396
- generic_pathname_insert('cutoff', lambda self: self.cutoff, setdefault=True)])
543
+ decorator=[
544
+ namebuilding_append(
545
+ "flow",
546
+ lambda self: None
547
+ if self.cutoff is None
548
+ else {"shortcutoff": self.cutoff},
549
+ none_discard=True,
550
+ ),
551
+ generic_pathname_insert(
552
+ "cutoff", lambda self: self.cutoff, setdefault=True
553
+ ),
554
+ ],
555
+ )
397
556
 
398
557
  #: Usual definition of the ``model`` attribute.
399
558
  a_model = dict(
400
559
  info="The model name (from a source code perspective).",
401
- alias=('turtle',),
560
+ alias=("turtle",),
402
561
  optional=False,
403
562
  values=models,
404
- remap=dict(
405
- arp='arpege',
406
- ald='aladin',
407
- aro='arome'
408
- ),
563
+ remap=dict(arp="arpege", ald="aladin", aro="arome"),
409
564
  )
410
565
 
411
- model = footprints.Footprint(info='Abstract model', attr=dict(model=a_model))
566
+ model = footprints.Footprint(info="Abstract model", attr=dict(model=a_model))
412
567
 
413
568
  model_deco = footprints.DecorativeFootprint(
414
569
  model,
415
- decorator=[namebuilding_append('src', lambda self: [self.model, ]),
416
- generic_pathname_insert('model', lambda self: self.model, setdefault=True)])
570
+ decorator=[
571
+ namebuilding_append(
572
+ "src",
573
+ lambda self: [
574
+ self.model,
575
+ ],
576
+ ),
577
+ generic_pathname_insert(
578
+ "model", lambda self: self.model, setdefault=True
579
+ ),
580
+ ],
581
+ )
417
582
 
418
583
  #: Usual definition of the ``date`` attribute.
419
584
  a_date = dict(
@@ -422,31 +587,50 @@ a_date = dict(
422
587
  optional=False,
423
588
  )
424
589
 
425
- date = footprints.Footprint(info='Abstract date', attr=dict(date=a_date))
590
+ date = footprints.Footprint(info="Abstract date", attr=dict(date=a_date))
426
591
 
427
592
  date_deco = footprints.DecorativeFootprint(
428
593
  date,
429
- decorator=[namebuilding_append('flow', lambda self: {'date': self.date}),
430
- generic_pathname_insert('date', lambda self: self.date, setdefault=True)])
594
+ decorator=[
595
+ namebuilding_append("flow", lambda self: {"date": self.date}),
596
+ generic_pathname_insert(
597
+ "date", lambda self: self.date, setdefault=True
598
+ ),
599
+ ],
600
+ )
431
601
 
432
602
  #: Usual definition of the ``begindate`` and ``enddate`` attributes.
433
603
 
434
- dateperiod = footprints.Footprint(info='Abstract date period',
435
- attr=dict(begindate=dict(info="The resource's begin date.",
436
- type=Date,
437
- optional=False),
438
- enddate=dict(info="The resource's end date.",
439
- type=Date,
440
- optional=False),
441
- ))
604
+ dateperiod = footprints.Footprint(
605
+ info="Abstract date period",
606
+ attr=dict(
607
+ begindate=dict(
608
+ info="The resource's begin date.", type=Date, optional=False
609
+ ),
610
+ enddate=dict(
611
+ info="The resource's end date.", type=Date, optional=False
612
+ ),
613
+ ),
614
+ )
442
615
 
443
616
  dateperiod_deco = footprints.DecorativeFootprint(
444
617
  dateperiod,
445
- decorator=[namebuilding_append('flow',
446
- lambda self: [{'begindate': self.begindate},
447
- {'enddate': self.enddate}]),
448
- generic_pathname_insert('begindate', lambda self: self.begindate, setdefault=True),
449
- generic_pathname_insert('enddate', lambda self: self.enddate, setdefault=True)])
618
+ decorator=[
619
+ namebuilding_append(
620
+ "flow",
621
+ lambda self: [
622
+ {"begindate": self.begindate},
623
+ {"enddate": self.enddate},
624
+ ],
625
+ ),
626
+ generic_pathname_insert(
627
+ "begindate", lambda self: self.begindate, setdefault=True
628
+ ),
629
+ generic_pathname_insert(
630
+ "enddate", lambda self: self.enddate, setdefault=True
631
+ ),
632
+ ],
633
+ )
450
634
 
451
635
  #: Usual definition of the ``month`` attribute.
452
636
  a_month = dict(
@@ -454,21 +638,23 @@ a_month = dict(
454
638
  type=Month,
455
639
  args=dict(year=0),
456
640
  optional=False,
457
- values=range(1, 13)
641
+ values=range(1, 13),
458
642
  )
459
643
 
460
- month = footprints.Footprint(info='Abstract month', attr=dict(month=a_month))
644
+ month = footprints.Footprint(info="Abstract month", attr=dict(month=a_month))
461
645
 
462
646
 
463
647
  def _add_month2gget_basename(cls):
464
648
  """Decorator that appends the month's number at the end of the gget_basename"""
465
- original_gget_basename = getattr(cls, 'gget_basename', None)
649
+ original_gget_basename = getattr(cls, "gget_basename", None)
466
650
  if original_gget_basename is not None:
467
651
 
468
652
  def gget_basename(self):
469
653
  """GGET specific naming convention."""
470
654
  b_dict = original_gget_basename(self)
471
- b_dict['suffix'] = b_dict.get('suffix', '') + '.m{!s}'.format(self.month)
655
+ b_dict["suffix"] = b_dict.get("suffix", "") + ".m{!s}".format(
656
+ self.month
657
+ )
472
658
  return b_dict
473
659
 
474
660
  cls.gget_basename = gget_basename
@@ -477,12 +663,12 @@ def _add_month2gget_basename(cls):
477
663
 
478
664
  def _add_month2olive_basename(cls):
479
665
  """Decorator that appends the month's number at the end of the olive_basename."""
480
- original_olive_basename = getattr(cls, 'olive_basename', None)
666
+ original_olive_basename = getattr(cls, "olive_basename", None)
481
667
  if original_olive_basename is not None:
482
668
 
483
669
  def olive_basename(self):
484
670
  """GGET specific naming convention."""
485
- return original_olive_basename(self) + '.{!s}'.format(self.month)
671
+ return original_olive_basename(self) + ".{!s}".format(self.month)
486
672
 
487
673
  cls.olive_basename = olive_basename
488
674
  return cls
@@ -490,8 +676,12 @@ def _add_month2olive_basename(cls):
490
676
 
491
677
  month_deco = footprints.DecorativeFootprint(
492
678
  month,
493
- decorator=[namebuilding_append('suffix', lambda self: {'month': self.month}),
494
- _add_month2gget_basename, _add_month2olive_basename])
679
+ decorator=[
680
+ namebuilding_append("suffix", lambda self: {"month": self.month}),
681
+ _add_month2gget_basename,
682
+ _add_month2olive_basename,
683
+ ],
684
+ )
495
685
 
496
686
  #: Usual definition of the ``truncation`` attribute.
497
687
  a_truncation = dict(
@@ -500,7 +690,9 @@ a_truncation = dict(
500
690
  optional=False,
501
691
  )
502
692
 
503
- truncation = footprints.Footprint(info='Abstract truncation', attr=dict(truncation=a_truncation))
693
+ truncation = footprints.Footprint(
694
+ info="Abstract truncation", attr=dict(truncation=a_truncation)
695
+ )
504
696
 
505
697
  #: Usual definition of the ``domain`` attribute.
506
698
  a_domain = dict(
@@ -508,7 +700,9 @@ a_domain = dict(
508
700
  optional=False,
509
701
  )
510
702
 
511
- domain = footprints.Footprint(info='Abstract domain', attr=dict(domain=a_domain))
703
+ domain = footprints.Footprint(
704
+ info="Abstract domain", attr=dict(domain=a_domain)
705
+ )
512
706
 
513
707
  #: Usual definition of the ``term`` attribute.
514
708
  a_term = dict(
@@ -517,39 +711,57 @@ a_term = dict(
517
711
  optional=False,
518
712
  )
519
713
 
520
- term = footprints.Footprint(info='Abstract term', attr=dict(term=a_term))
714
+ term = footprints.Footprint(info="Abstract term", attr=dict(term=a_term))
521
715
 
522
716
  term_deco = footprints.DecorativeFootprint(
523
717
  term,
524
- decorator=[namebuilding_insert('term',
525
- lambda self: None if self.term is None else self.term.fmthm,
526
- none_discard=True, setdefault=True), ])
718
+ decorator=[
719
+ namebuilding_insert(
720
+ "term",
721
+ lambda self: None if self.term is None else self.term.fmthm,
722
+ none_discard=True,
723
+ setdefault=True,
724
+ ),
725
+ ],
726
+ )
527
727
 
528
728
  #: Usual definition of the ``begintime`` and ``endtime`` attributes.
529
729
 
530
- timeperiod = footprints.Footprint(info='Abstract Time Period',
531
- attr=dict(begintime=dict(info="The resource's begin forecast term.",
532
- type=Time,
533
- optional=False),
534
- endtime=dict(info="The resource's end forecast term.",
535
- type=Time,
536
- optional=False),
537
- ))
730
+ timeperiod = footprints.Footprint(
731
+ info="Abstract Time Period",
732
+ attr=dict(
733
+ begintime=dict(
734
+ info="The resource's begin forecast term.",
735
+ type=Time,
736
+ optional=False,
737
+ ),
738
+ endtime=dict(
739
+ info="The resource's end forecast term.", type=Time, optional=False
740
+ ),
741
+ ),
742
+ )
538
743
 
539
744
  timeperiod_deco = footprints.DecorativeFootprint(
540
745
  timeperiod,
541
- decorator=[namebuilding_insert('period',
542
- lambda self: [{'begintime': self.begintime},
543
- {'endtime': self.endtime}]), ])
746
+ decorator=[
747
+ namebuilding_insert(
748
+ "period",
749
+ lambda self: [
750
+ {"begintime": self.begintime},
751
+ {"endtime": self.endtime},
752
+ ],
753
+ ),
754
+ ],
755
+ )
544
756
 
545
757
  #: Usual definition of operational suite
546
758
  a_suite = dict(
547
759
  info="The operational suite identifier.",
548
- values=['oper', 'dble', 'dbl', 'test', 'mirr', 'miroir'],
760
+ values=["oper", "dble", "dbl", "test", "mirr", "miroir"],
549
761
  remap=dict(
550
- dbl='dble',
551
- miroir='mirr',
552
- )
762
+ dbl="dble",
763
+ miroir="mirr",
764
+ ),
553
765
  )
554
766
 
555
767
  #: Usual definition of the ``member`` attribute
@@ -559,7 +771,9 @@ a_member = dict(
559
771
  optional=True,
560
772
  )
561
773
 
562
- member = footprints.Footprint(info='Abstract member', attr=dict(member=a_member))
774
+ member = footprints.Footprint(
775
+ info="Abstract member", attr=dict(member=a_member)
776
+ )
563
777
 
564
778
  #: Usual definition of the ``scenario`` attribute
565
779
  a_scenario = dict(
@@ -567,27 +781,36 @@ a_scenario = dict(
567
781
  optional=True,
568
782
  )
569
783
 
570
- scenario = footprints.Footprint(info='Abstract scenario', attr=dict(scenario=a_scenario))
784
+ scenario = footprints.Footprint(
785
+ info="Abstract scenario", attr=dict(scenario=a_scenario)
786
+ )
571
787
 
572
788
  #: Usual definition of the ``number`` attribute (e.g. a perturbation number)
573
789
  a_number = dict(
574
790
  info="Any kind of numbering...",
575
791
  type=FmtInt,
576
- args=dict(fmt='03'),
792
+ args=dict(fmt="03"),
577
793
  )
578
794
 
579
- number = footprints.Footprint(info='Abstract number', attr=dict(number=a_number))
795
+ number = footprints.Footprint(
796
+ info="Abstract number", attr=dict(number=a_number)
797
+ )
580
798
 
581
799
  number_deco = footprints.DecorativeFootprint(
582
800
  number,
583
- decorator=[namebuilding_insert('number', lambda self: self.number, setdefault=True), ])
801
+ decorator=[
802
+ namebuilding_insert(
803
+ "number", lambda self: self.number, setdefault=True
804
+ ),
805
+ ],
806
+ )
584
807
 
585
808
  #: Usual definition of the ``block`` attribute
586
809
  a_block = dict(
587
- info='The subpath where to store the data.',
810
+ info="The subpath where to store the data.",
588
811
  )
589
812
 
590
- block = footprints.Footprint(info='Abstract block', attr=dict(block=a_block))
813
+ block = footprints.Footprint(info="Abstract block", attr=dict(block=a_block))
591
814
 
592
815
  #: Usual definition of the ``namespace`` attribute
593
816
  a_namespace = dict(
@@ -596,17 +819,22 @@ a_namespace = dict(
596
819
  optional=True,
597
820
  )
598
821
 
599
- namespacefp = footprints.Footprint(info='Abstract namespace',
600
- attr=dict(namespace=a_namespace))
822
+ namespacefp = footprints.Footprint(
823
+ info="Abstract namespace", attr=dict(namespace=a_namespace)
824
+ )
601
825
 
602
826
  #: Usual definition of the ``storehash`` attribute
603
827
  a_hashalgo = dict(
604
828
  info="The hash algorithm used to check data integrity",
605
829
  optional=True,
606
- values=[None, ],
830
+ values=[
831
+ None,
832
+ ],
607
833
  )
608
834
 
609
- hashalgo = footprints.Footprint(info='Abstract Hash Algo', attr=dict(storehash=a_hashalgo))
835
+ hashalgo = footprints.Footprint(
836
+ info="Abstract Hash Algo", attr=dict(storehash=a_hashalgo)
837
+ )
610
838
 
611
839
  hashalgo_avail_list = hashutils.HashAdapter.algorithms()
612
840
 
@@ -616,13 +844,24 @@ a_compressionpipeline = dict(
616
844
  optional=True,
617
845
  )
618
846
 
619
- compressionpipeline = footprints.Footprint(info='Abstract Compression Pipeline',
620
- attr=dict(store_compressed=a_compressionpipeline))
847
+ compressionpipeline = footprints.Footprint(
848
+ info="Abstract Compression Pipeline",
849
+ attr=dict(store_compressed=a_compressionpipeline),
850
+ )
621
851
 
622
852
 
623
853
  def show():
624
854
  """Returns available items and their type."""
625
855
  dmod = globals()
626
- for stda in sorted(filter(lambda x: x.startswith('a_') or isinstance(dmod[x], footprints.Footprint),
627
- dmod.keys())):
628
- print('{} ( {} ) :\n {}\n'.format(stda, type(dmod[stda]).__name__, dmod[stda]))
856
+ for stda in sorted(
857
+ filter(
858
+ lambda x: x.startswith("a_")
859
+ or isinstance(dmod[x], footprints.Footprint),
860
+ dmod.keys(),
861
+ )
862
+ ):
863
+ print(
864
+ "{} ( {} ) :\n {}\n".format(
865
+ stda, type(dmod[stda]).__name__, dmod[stda]
866
+ )
867
+ )