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
@@ -14,43 +14,45 @@ __all__ = []
14
14
  logger = loggers.getLogger(__name__)
15
15
 
16
16
 
17
- class OdbMonitoring(Parallel, odb.OdbComponentDecoMixin, drhook.DrHookDecoMixin):
17
+ class OdbMonitoring(
18
+ Parallel, odb.OdbComponentDecoMixin, drhook.DrHookDecoMixin
19
+ ):
18
20
  """Compute monitoring statistics."""
19
21
 
20
22
  _footprint = dict(
21
- attr = dict(
22
- kind = dict(
23
- values = ['monitoring'],
23
+ attr=dict(
24
+ kind=dict(
25
+ values=["monitoring"],
24
26
  ),
25
- npool = dict(
26
- default = 1,
27
- optional = True,
27
+ npool=dict(
28
+ default=1,
29
+ optional=True,
28
30
  ),
29
- obs = dict(
30
- values = ['all', 'used'],
31
+ obs=dict(
32
+ values=["all", "used"],
31
33
  ),
32
- date = a_date,
33
- model= a_model,
34
- cutoff = a_cutoff,
35
- start = dict(
36
- type = bool,
37
- default = False,
38
- optional = True,
34
+ date=a_date,
35
+ model=a_model,
36
+ cutoff=a_cutoff,
37
+ start=dict(
38
+ type=bool,
39
+ default=False,
40
+ optional=True,
39
41
  ),
40
- cumul = dict(
41
- type = bool,
42
- default = True,
43
- optional = True,
42
+ cumul=dict(
43
+ type=bool,
44
+ default=True,
45
+ optional=True,
44
46
  ),
45
- extend = dict(
46
- type = bool,
47
- default = False,
48
- optional = True,
47
+ extend=dict(
48
+ type=bool,
49
+ default=False,
50
+ optional=True,
49
51
  ),
50
- stage = dict(
51
- values = ['can', 'surf', 'surface', 'atm', 'atmospheric'],
52
- remap = dict(can='surf', surface='surf', atmospheric='atm'),
53
- info = 'The processing stage of the ODB base.',
52
+ stage=dict(
53
+ values=["can", "surf", "surface", "atm", "atmospheric"],
54
+ remap=dict(can="surf", surface="surf", atmospheric="atm"),
55
+ info="The processing stage of the ODB base.",
54
56
  ),
55
57
  )
56
58
  )
@@ -58,7 +60,12 @@ class OdbMonitoring(Parallel, odb.OdbComponentDecoMixin, drhook.DrHookDecoMixin)
58
60
  def _fix_nam_macro(self, rh, macro, value):
59
61
  """Set a given namelist macro and issue a log message."""
60
62
  rh.contents.setmacro(macro, value)
61
- logger.info('Setup %s macro to %s in %s', macro, value, rh.container.actualpath())
63
+ logger.info(
64
+ "Setup %s macro to %s in %s",
65
+ macro,
66
+ value,
67
+ rh.container.actualpath(),
68
+ )
62
69
 
63
70
  def prepare(self, rh, opts):
64
71
  """Update some variables in the namelist and check the presence of the accumulated statistics file."""
@@ -69,31 +76,42 @@ class OdbMonitoring(Parallel, odb.OdbComponentDecoMixin, drhook.DrHookDecoMixin)
69
76
 
70
77
  # Virtual upper-air observations database
71
78
  obsatm_virt = [
72
- x for x in self.lookupodb(fatal=False)
73
- if (x.rh.resource.stage.startswith('matchup') or
74
- x.rh.resource.stage.startswith('screening')) and x.rh.resource.part == 'virtual'
79
+ x
80
+ for x in self.lookupodb(fatal=False)
81
+ if (
82
+ x.rh.resource.stage.startswith("matchup")
83
+ or x.rh.resource.stage.startswith("screening")
84
+ )
85
+ and x.rh.resource.part == "virtual"
75
86
  ]
76
87
 
77
88
  # Single upper-air observations database
78
89
  obsatm_single = [
79
- x for x in self.lookupodb(fatal=False)
80
- if x.rh.resource.stage.startswith('matchup') or x.rh.resource.stage.startswith('screening')
90
+ x
91
+ for x in self.lookupodb(fatal=False)
92
+ if x.rh.resource.stage.startswith("matchup")
93
+ or x.rh.resource.stage.startswith("screening")
81
94
  ]
82
95
  if len(obsatm_single) > 1:
83
96
  obsatm_single = []
84
97
 
85
98
  # Surface observations database
86
99
  obssurf = [
87
- x for x in self.lookupodb(fatal=False)
88
- if x.rh.resource.stage.startswith('canari') and (x.rh.resource.part == 'surf' or
89
- x.rh.resource.part == 'ground')
100
+ x
101
+ for x in self.lookupodb(fatal=False)
102
+ if x.rh.resource.stage.startswith("canari")
103
+ and (
104
+ x.rh.resource.part == "surf" or x.rh.resource.part == "ground"
105
+ )
90
106
  ]
91
107
 
92
108
  # One database at a time
93
- if not (obsatm_virt or obsatm_single) and self.stage == 'atm':
94
- raise ValueError('Could not find any ODB matchup or screening ECMA database')
95
- if not obssurf and self.stage == 'surf':
96
- raise ValueError('Could not find any ODB surface ECMA database')
109
+ if not (obsatm_virt or obsatm_single) and self.stage == "atm":
110
+ raise ValueError(
111
+ "Could not find any ODB matchup or screening ECMA database"
112
+ )
113
+ if not obssurf and self.stage == "surf":
114
+ raise ValueError("Could not find any ODB surface ECMA database")
97
115
 
98
116
  # Set actual ODB paths
99
117
  if obsatm_virt:
@@ -104,8 +122,12 @@ class OdbMonitoring(Parallel, odb.OdbComponentDecoMixin, drhook.DrHookDecoMixin)
104
122
  ecma = obssurf.pop(0)
105
123
  ecma_path = sh.path.abspath(ecma.rh.container.localpath())
106
124
  self.odb.fix_db_path(ecma.rh.resource.layout, ecma_path)
107
- self.env.IOASSIGN = sh.path.join(ecma_path, 'IOASSIGN')
108
- logger.info('Setting ODB env %s = %s.', 'IOASSIGN', sh.path.join(ecma_path, 'IOASSIGN'))
125
+ self.env.IOASSIGN = sh.path.join(ecma_path, "IOASSIGN")
126
+ logger.info(
127
+ "Setting ODB env %s = %s.",
128
+ "IOASSIGN",
129
+ sh.path.join(ecma_path, "IOASSIGN"),
130
+ )
109
131
 
110
132
  # Let ancestors handling most of the env setting
111
133
  super().prepare(rh, opts)
@@ -113,69 +135,103 @@ class OdbMonitoring(Parallel, odb.OdbComponentDecoMixin, drhook.DrHookDecoMixin)
113
135
  # Force to start a new accumulated statistics file if first day and first hour of the month
114
136
  mnt_start = self.start
115
137
 
116
- if not mnt_start and int(self.date.day) == 1 and int(self.date.hh) == 0 and not self.extend:
117
- logger.info('First day and first hour of the month : force start attribute to True.')
138
+ if (
139
+ not mnt_start
140
+ and int(self.date.day) == 1
141
+ and int(self.date.hh) == 0
142
+ and not self.extend
143
+ ):
144
+ logger.info(
145
+ "First day and first hour of the month : force start attribute to True."
146
+ )
118
147
  mnt_start = True
119
148
 
120
149
  mnt_cumul = self.cumul
121
- if self.cutoff == 'production':
150
+ if self.cutoff == "production":
122
151
  mnt_cumul = False
123
- logger.info('No output accumulated statistics file will be produced because '
124
- 'cutoff = production : force cumul to False')
152
+ logger.info(
153
+ "No output accumulated statistics file will be produced because "
154
+ "cutoff = production : force cumul to False"
155
+ )
125
156
 
126
157
  # Monitoring namelist
127
158
  namrh = self.context.sequence.effective_inputs(
128
- role='Namelist',
129
- kind='namelist',)
159
+ role="Namelist",
160
+ kind="namelist",
161
+ )
130
162
  if len(namrh) != 1:
131
- logger.critical('There must be exactly one namelist for monitoring. Stop.')
132
- raise ValueError('There must be exactly one namelist for monitoring. Stop.')
163
+ logger.critical(
164
+ "There must be exactly one namelist for monitoring. Stop."
165
+ )
166
+ raise ValueError(
167
+ "There must be exactly one namelist for monitoring. Stop."
168
+ )
133
169
  namrh = namrh[0].rh
134
170
 
135
171
  # Cumulated statistics file
136
172
  cumulrh = self.context.sequence.effective_inputs(
137
- role='Cumulated monitoring statistics',
138
- kind='accumulated_stats',
173
+ role="Cumulated monitoring statistics",
174
+ kind="accumulated_stats",
139
175
  )
140
176
 
141
177
  if len(cumulrh) > 1:
142
- logger.critical('There must be at most one accumulated statistics file.Stop.')
143
- raise ValueError('There must be one accumulated statistics file or none.Stop.')
178
+ logger.critical(
179
+ "There must be at most one accumulated statistics file.Stop."
180
+ )
181
+ raise ValueError(
182
+ "There must be one accumulated statistics file or none.Stop."
183
+ )
144
184
  else:
145
185
  if len(cumulrh) == 0:
146
186
  if not mnt_start:
147
187
  if mnt_cumul:
148
- logger.critical('There must be one input accumulated statistics file. Stop.')
149
- raise ValueError('There must be one input accumulated statistics file. Stop.')
188
+ logger.critical(
189
+ "There must be one input accumulated statistics file. Stop."
190
+ )
191
+ raise ValueError(
192
+ "There must be one input accumulated statistics file. Stop."
193
+ )
150
194
  else:
151
- logger.info('No input accumulated statistics file is necessary.')
152
- logger.info('No output accumulated statistics file will be produced.')
195
+ logger.info(
196
+ "No input accumulated statistics file is necessary."
197
+ )
198
+ logger.info(
199
+ "No output accumulated statistics file will be produced."
200
+ )
153
201
  else:
154
202
  if mnt_cumul:
155
- logger.info('No input accumulated statistics file. It will be created by the binary.')
203
+ logger.info(
204
+ "No input accumulated statistics file. It will be created by the binary."
205
+ )
156
206
  else:
157
- logger.info('No output accumulated statistics file will be produced.')
207
+ logger.info(
208
+ "No output accumulated statistics file will be produced."
209
+ )
158
210
  else:
159
211
  cumulrh = cumulrh[0].rh
160
212
  if not mnt_cumul:
161
- logger.info('No input accumulated statistics file is necessary(start=False).')
213
+ logger.info(
214
+ "No input accumulated statistics file is necessary(start=False)."
215
+ )
162
216
  cumulrh.container.clear()
163
217
  else:
164
218
  if mnt_start:
165
- logger.info('No input accumulated statistics file is necessary (start=True)')
219
+ logger.info(
220
+ "No input accumulated statistics file is necessary (start=True)"
221
+ )
166
222
  cumulrh.container.clear()
167
223
 
168
- self._fix_nam_macro(namrh, 'JOUR', int(self.date.ymd))
169
- self._fix_nam_macro(namrh, 'RES', int(self.date.hh))
224
+ self._fix_nam_macro(namrh, "JOUR", int(self.date.ymd))
225
+ self._fix_nam_macro(namrh, "RES", int(self.date.hh))
170
226
 
171
- self._fix_nam_macro(namrh, 'LLADMON', mnt_cumul)
172
- self._fix_nam_macro(namrh, 'LLADAJ', mnt_cumul and not mnt_start)
227
+ self._fix_nam_macro(namrh, "LLADMON", mnt_cumul)
228
+ self._fix_nam_macro(namrh, "LLADAJ", mnt_cumul and not mnt_start)
173
229
 
174
- self._fix_nam_macro(namrh, 'LLFLAG', self.obs != 'all')
230
+ self._fix_nam_macro(namrh, "LLFLAG", self.obs != "all")
175
231
 
176
- self._fix_nam_macro(namrh, 'LLARO', self.model == 'arome')
177
- self._fix_nam_macro(namrh, 'LLVRP', self.model == 'varpack')
178
- self._fix_nam_macro(namrh, 'LLCAN', self.stage == 'surf')
232
+ self._fix_nam_macro(namrh, "LLARO", self.model == "arome")
233
+ self._fix_nam_macro(namrh, "LLVRP", self.model == "varpack")
234
+ self._fix_nam_macro(namrh, "LLCAN", self.stage == "surf")
179
235
 
180
236
  if namrh.contents.dumps_needs_update:
181
237
  namrh.contents.rewrite(namrh.container)
@@ -189,13 +245,13 @@ class OdbMonitoring(Parallel, odb.OdbComponentDecoMixin, drhook.DrHookDecoMixin)
189
245
  allfiles = sh.ls()
190
246
  for f in allfiles:
191
247
  if self.system.path.getsize(f) == 0:
192
- logger.info('Remove %s because size of %s is zero.', f, f)
248
+ logger.info("Remove %s because size of %s is zero.", f, f)
193
249
  sh.remove(f)
194
250
 
195
- obspoint_out = sh.ls('point.*')
251
+ obspoint_out = sh.ls("point.*")
196
252
  if obspoint_out:
197
- dest = 'obslocationpack'
198
- logger.info('Creating an OBSLOCATION pack: %s', dest)
253
+ dest = "obslocationpack"
254
+ logger.info("Creating an OBSLOCATION pack: %s", dest)
199
255
  sh.mkdir(dest)
200
256
  for fname in obspoint_out:
201
257
  sh.mv(fname, dest)