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.
- vortex/__init__.py +59 -45
- vortex/algo/__init__.py +3 -2
- vortex/algo/components.py +940 -614
- vortex/algo/mpitools.py +802 -497
- vortex/algo/serversynctools.py +34 -33
- vortex/config.py +19 -22
- vortex/data/__init__.py +9 -3
- vortex/data/abstractstores.py +593 -655
- vortex/data/containers.py +217 -162
- vortex/data/contents.py +65 -39
- vortex/data/executables.py +93 -102
- vortex/data/flow.py +40 -34
- vortex/data/geometries.py +228 -132
- vortex/data/handlers.py +428 -225
- vortex/data/outflow.py +15 -15
- vortex/data/providers.py +185 -163
- vortex/data/resources.py +48 -42
- vortex/data/stores.py +544 -413
- vortex/gloves.py +114 -87
- vortex/layout/__init__.py +1 -8
- vortex/layout/contexts.py +150 -84
- vortex/layout/dataflow.py +353 -202
- vortex/layout/monitor.py +264 -128
- vortex/nwp/__init__.py +5 -2
- vortex/nwp/algo/__init__.py +14 -5
- vortex/nwp/algo/assim.py +205 -151
- vortex/nwp/algo/clim.py +683 -517
- vortex/nwp/algo/coupling.py +447 -225
- vortex/nwp/algo/eda.py +437 -229
- vortex/nwp/algo/eps.py +403 -231
- vortex/nwp/algo/forecasts.py +420 -271
- vortex/nwp/algo/fpserver.py +683 -307
- vortex/nwp/algo/ifsnaming.py +205 -145
- vortex/nwp/algo/ifsroot.py +210 -122
- vortex/nwp/algo/monitoring.py +132 -76
- vortex/nwp/algo/mpitools.py +321 -191
- vortex/nwp/algo/odbtools.py +617 -353
- vortex/nwp/algo/oopsroot.py +449 -273
- vortex/nwp/algo/oopstests.py +90 -56
- vortex/nwp/algo/request.py +287 -206
- vortex/nwp/algo/stdpost.py +878 -522
- vortex/nwp/data/__init__.py +22 -4
- vortex/nwp/data/assim.py +125 -137
- vortex/nwp/data/boundaries.py +121 -68
- vortex/nwp/data/climfiles.py +193 -211
- vortex/nwp/data/configfiles.py +73 -69
- vortex/nwp/data/consts.py +426 -401
- vortex/nwp/data/ctpini.py +59 -43
- vortex/nwp/data/diagnostics.py +94 -66
- vortex/nwp/data/eda.py +50 -51
- vortex/nwp/data/eps.py +195 -146
- vortex/nwp/data/executables.py +440 -434
- vortex/nwp/data/fields.py +63 -48
- vortex/nwp/data/gridfiles.py +183 -111
- vortex/nwp/data/logs.py +250 -217
- vortex/nwp/data/modelstates.py +180 -151
- vortex/nwp/data/monitoring.py +72 -99
- vortex/nwp/data/namelists.py +254 -202
- vortex/nwp/data/obs.py +400 -308
- vortex/nwp/data/oopsexec.py +22 -20
- vortex/nwp/data/providers.py +90 -65
- vortex/nwp/data/query.py +71 -82
- vortex/nwp/data/stores.py +49 -36
- vortex/nwp/data/surfex.py +136 -137
- vortex/nwp/syntax/__init__.py +1 -1
- vortex/nwp/syntax/stdattrs.py +173 -111
- vortex/nwp/tools/__init__.py +2 -2
- vortex/nwp/tools/addons.py +22 -17
- vortex/nwp/tools/agt.py +24 -12
- vortex/nwp/tools/bdap.py +16 -5
- vortex/nwp/tools/bdcp.py +4 -1
- vortex/nwp/tools/bdm.py +3 -0
- vortex/nwp/tools/bdmp.py +14 -9
- vortex/nwp/tools/conftools.py +728 -378
- vortex/nwp/tools/drhook.py +12 -8
- vortex/nwp/tools/grib.py +65 -39
- vortex/nwp/tools/gribdiff.py +22 -17
- vortex/nwp/tools/ifstools.py +82 -42
- vortex/nwp/tools/igastuff.py +167 -143
- vortex/nwp/tools/mars.py +14 -2
- vortex/nwp/tools/odb.py +234 -125
- vortex/nwp/tools/partitioning.py +61 -37
- vortex/nwp/tools/satrad.py +27 -12
- vortex/nwp/util/async.py +83 -55
- vortex/nwp/util/beacon.py +10 -10
- vortex/nwp/util/diffpygram.py +174 -86
- vortex/nwp/util/ens.py +144 -63
- vortex/nwp/util/hooks.py +30 -19
- vortex/nwp/util/taskdeco.py +28 -24
- vortex/nwp/util/usepygram.py +278 -172
- vortex/nwp/util/usetnt.py +31 -17
- vortex/sessions.py +72 -39
- vortex/syntax/__init__.py +1 -1
- vortex/syntax/stdattrs.py +410 -171
- vortex/syntax/stddeco.py +31 -22
- vortex/toolbox.py +327 -192
- vortex/tools/__init__.py +11 -2
- vortex/tools/actions.py +125 -59
- vortex/tools/addons.py +111 -92
- vortex/tools/arm.py +42 -22
- vortex/tools/compression.py +72 -69
- vortex/tools/date.py +11 -4
- vortex/tools/delayedactions.py +242 -132
- vortex/tools/env.py +75 -47
- vortex/tools/folder.py +342 -171
- vortex/tools/grib.py +311 -149
- vortex/tools/lfi.py +423 -216
- vortex/tools/listings.py +109 -40
- vortex/tools/names.py +218 -156
- vortex/tools/net.py +632 -298
- vortex/tools/parallelism.py +93 -61
- vortex/tools/prestaging.py +55 -31
- vortex/tools/schedulers.py +172 -105
- vortex/tools/services.py +402 -333
- vortex/tools/storage.py +293 -358
- vortex/tools/surfex.py +24 -24
- vortex/tools/systems.py +1211 -631
- vortex/tools/targets.py +156 -100
- vortex/util/__init__.py +1 -1
- vortex/util/config.py +377 -327
- vortex/util/empty.py +2 -2
- vortex/util/helpers.py +56 -24
- vortex/util/introspection.py +18 -12
- vortex/util/iosponge.py +8 -4
- vortex/util/roles.py +4 -6
- vortex/util/storefunctions.py +39 -13
- vortex/util/structs.py +3 -3
- vortex/util/worker.py +29 -17
- vortex_nwp-2.0.0b2.dist-info/METADATA +66 -0
- vortex_nwp-2.0.0b2.dist-info/RECORD +142 -0
- {vortex_nwp-2.0.0b1.dist-info → vortex_nwp-2.0.0b2.dist-info}/WHEEL +1 -1
- vortex/layout/appconf.py +0 -109
- vortex/layout/jobs.py +0 -1276
- vortex/layout/nodes.py +0 -1424
- vortex/layout/subjobs.py +0 -464
- vortex_nwp-2.0.0b1.dist-info/METADATA +0 -50
- vortex_nwp-2.0.0b1.dist-info/RECORD +0 -146
- {vortex_nwp-2.0.0b1.dist-info → vortex_nwp-2.0.0b2.dist-info}/LICENSE +0 -0
- {vortex_nwp-2.0.0b1.dist-info → vortex_nwp-2.0.0b2.dist-info}/top_level.txt +0 -0
vortex/nwp/algo/monitoring.py
CHANGED
|
@@ -14,43 +14,45 @@ __all__ = []
|
|
|
14
14
|
logger = loggers.getLogger(__name__)
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
class OdbMonitoring(
|
|
17
|
+
class OdbMonitoring(
|
|
18
|
+
Parallel, odb.OdbComponentDecoMixin, drhook.DrHookDecoMixin
|
|
19
|
+
):
|
|
18
20
|
"""Compute monitoring statistics."""
|
|
19
21
|
|
|
20
22
|
_footprint = dict(
|
|
21
|
-
attr
|
|
22
|
-
kind
|
|
23
|
-
values
|
|
23
|
+
attr=dict(
|
|
24
|
+
kind=dict(
|
|
25
|
+
values=["monitoring"],
|
|
24
26
|
),
|
|
25
|
-
npool
|
|
26
|
-
default
|
|
27
|
-
optional
|
|
27
|
+
npool=dict(
|
|
28
|
+
default=1,
|
|
29
|
+
optional=True,
|
|
28
30
|
),
|
|
29
|
-
obs
|
|
30
|
-
values
|
|
31
|
+
obs=dict(
|
|
32
|
+
values=["all", "used"],
|
|
31
33
|
),
|
|
32
|
-
date
|
|
33
|
-
model=
|
|
34
|
-
cutoff
|
|
35
|
-
start
|
|
36
|
-
type
|
|
37
|
-
default
|
|
38
|
-
optional
|
|
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
|
|
41
|
-
type
|
|
42
|
-
default
|
|
43
|
-
optional
|
|
42
|
+
cumul=dict(
|
|
43
|
+
type=bool,
|
|
44
|
+
default=True,
|
|
45
|
+
optional=True,
|
|
44
46
|
),
|
|
45
|
-
extend
|
|
46
|
-
type
|
|
47
|
-
default
|
|
48
|
-
optional
|
|
47
|
+
extend=dict(
|
|
48
|
+
type=bool,
|
|
49
|
+
default=False,
|
|
50
|
+
optional=True,
|
|
49
51
|
),
|
|
50
|
-
stage
|
|
51
|
-
values
|
|
52
|
-
remap
|
|
53
|
-
info
|
|
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(
|
|
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
|
|
73
|
-
|
|
74
|
-
|
|
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
|
|
80
|
-
|
|
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
|
|
88
|
-
|
|
89
|
-
|
|
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 ==
|
|
94
|
-
raise ValueError(
|
|
95
|
-
|
|
96
|
-
|
|
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,
|
|
108
|
-
logger.info(
|
|
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
|
|
117
|
-
|
|
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 ==
|
|
150
|
+
if self.cutoff == "production":
|
|
122
151
|
mnt_cumul = False
|
|
123
|
-
logger.info(
|
|
124
|
-
|
|
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=
|
|
129
|
-
kind=
|
|
159
|
+
role="Namelist",
|
|
160
|
+
kind="namelist",
|
|
161
|
+
)
|
|
130
162
|
if len(namrh) != 1:
|
|
131
|
-
logger.critical(
|
|
132
|
-
|
|
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=
|
|
138
|
-
kind=
|
|
173
|
+
role="Cumulated monitoring statistics",
|
|
174
|
+
kind="accumulated_stats",
|
|
139
175
|
)
|
|
140
176
|
|
|
141
177
|
if len(cumulrh) > 1:
|
|
142
|
-
logger.critical(
|
|
143
|
-
|
|
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(
|
|
149
|
-
|
|
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(
|
|
152
|
-
|
|
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(
|
|
203
|
+
logger.info(
|
|
204
|
+
"No input accumulated statistics file. It will be created by the binary."
|
|
205
|
+
)
|
|
156
206
|
else:
|
|
157
|
-
logger.info(
|
|
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(
|
|
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(
|
|
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,
|
|
169
|
-
self._fix_nam_macro(namrh,
|
|
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,
|
|
172
|
-
self._fix_nam_macro(namrh,
|
|
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,
|
|
230
|
+
self._fix_nam_macro(namrh, "LLFLAG", self.obs != "all")
|
|
175
231
|
|
|
176
|
-
self._fix_nam_macro(namrh,
|
|
177
|
-
self._fix_nam_macro(namrh,
|
|
178
|
-
self._fix_nam_macro(namrh,
|
|
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(
|
|
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(
|
|
251
|
+
obspoint_out = sh.ls("point.*")
|
|
196
252
|
if obspoint_out:
|
|
197
|
-
dest =
|
|
198
|
-
logger.info(
|
|
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)
|