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.
- vortex/__init__.py +75 -47
- vortex/algo/__init__.py +3 -2
- vortex/algo/components.py +944 -618
- vortex/algo/mpitools.py +802 -497
- vortex/algo/mpitools_templates/__init__.py +1 -0
- 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 +436 -227
- vortex/data/outflow.py +15 -15
- vortex/data/providers.py +185 -163
- vortex/data/resources.py +48 -42
- vortex/data/stores.py +540 -417
- vortex/data/sync_templates/__init__.py +0 -0
- 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 +416 -275
- vortex/nwp/algo/fpserver.py +683 -307
- vortex/nwp/algo/ifsnaming.py +205 -145
- vortex/nwp/algo/ifsroot.py +215 -122
- vortex/nwp/algo/monitoring.py +137 -76
- vortex/nwp/algo/mpitools.py +330 -190
- vortex/nwp/algo/odbtools.py +637 -353
- vortex/nwp/algo/oopsroot.py +454 -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 +110 -121
- 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 +341 -162
- vortex/tools/lfi.py +423 -216
- vortex/tools/listings.py +109 -40
- vortex/tools/names.py +218 -156
- vortex/tools/net.py +655 -299
- vortex/tools/parallelism.py +93 -61
- vortex/tools/prestaging.py +55 -31
- vortex/tools/schedulers.py +172 -105
- vortex/tools/services.py +403 -334
- vortex/tools/storage.py +293 -358
- vortex/tools/surfex.py +24 -24
- vortex/tools/systems.py +1234 -643
- vortex/tools/targets.py +156 -100
- vortex/util/__init__.py +1 -1
- vortex/util/config.py +378 -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.1.0.dist-info/METADATA +67 -0
- vortex_nwp-2.1.0.dist-info/RECORD +144 -0
- {vortex_nwp-2.0.0b1.dist-info → vortex_nwp-2.1.0.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.1.0.dist-info/licenses}/LICENSE +0 -0
- {vortex_nwp-2.0.0b1.dist-info → vortex_nwp-2.1.0.dist-info}/top_level.txt +0 -0
vortex/nwp/algo/request.py
CHANGED
|
@@ -8,11 +8,20 @@ from bronx.fancies import loggers
|
|
|
8
8
|
from bronx.stdtypes.date import Time
|
|
9
9
|
import footprints
|
|
10
10
|
|
|
11
|
-
from vortex.algo.components import
|
|
11
|
+
from vortex.algo.components import (
|
|
12
|
+
AlgoComponent,
|
|
13
|
+
AlgoComponentDecoMixin,
|
|
14
|
+
Expresso,
|
|
15
|
+
BlindRun,
|
|
16
|
+
)
|
|
12
17
|
from vortex.algo.components import algo_component_deco_mixin_autodoc
|
|
13
18
|
from vortex.syntax.stdattrs import a_date
|
|
14
19
|
from vortex.tools.systems import ExecutionError
|
|
15
|
-
from ..tools.bdap import
|
|
20
|
+
from ..tools.bdap import (
|
|
21
|
+
BDAPrequest_actual_command,
|
|
22
|
+
BDAPGetError,
|
|
23
|
+
BDAPRequestConfigurationError,
|
|
24
|
+
)
|
|
16
25
|
from ..tools.bdmp import BDMPrequest_actual_command, BDMPGetError
|
|
17
26
|
from ..tools.bdcp import BDCPrequest_actual_command, BDCPGetError
|
|
18
27
|
from ..tools.bdm import BDMGetError, BDMRequestConfigurationError, BDMError
|
|
@@ -29,27 +38,27 @@ class GetBDAPResource(AlgoComponent):
|
|
|
29
38
|
"""Algo component to get BDAP resources considering a BDAP query file."""
|
|
30
39
|
|
|
31
40
|
_footprint = dict(
|
|
32
|
-
info
|
|
33
|
-
attr
|
|
34
|
-
kind
|
|
35
|
-
values
|
|
41
|
+
info="Algo component to get BDAP files.",
|
|
42
|
+
attr=dict(
|
|
43
|
+
kind=dict(
|
|
44
|
+
values=["get_bdap"],
|
|
36
45
|
),
|
|
37
|
-
date
|
|
38
|
-
target_bdap
|
|
39
|
-
default
|
|
40
|
-
optional
|
|
41
|
-
values
|
|
46
|
+
date=a_date,
|
|
47
|
+
target_bdap=dict(
|
|
48
|
+
default="OPER",
|
|
49
|
+
optional=True,
|
|
50
|
+
values=["OPER", "INTE"],
|
|
42
51
|
),
|
|
43
|
-
terms
|
|
44
|
-
info
|
|
45
|
-
alias
|
|
52
|
+
terms=dict(
|
|
53
|
+
info="A forecast term or a list of terms (rangex will be used to expand the string)",
|
|
54
|
+
alias=("term",),
|
|
46
55
|
),
|
|
47
|
-
command
|
|
48
|
-
default
|
|
49
|
-
optional
|
|
50
|
-
values
|
|
56
|
+
command=dict(
|
|
57
|
+
default="dap3",
|
|
58
|
+
optional=True,
|
|
59
|
+
values=["dap3", "dap3_dev"],
|
|
51
60
|
),
|
|
52
|
-
)
|
|
61
|
+
),
|
|
53
62
|
)
|
|
54
63
|
|
|
55
64
|
def execute_single(self, rh, opts):
|
|
@@ -60,40 +69,54 @@ class GetBDAPResource(AlgoComponent):
|
|
|
60
69
|
"""
|
|
61
70
|
|
|
62
71
|
# Determine the target BDAP
|
|
63
|
-
int_bdap = self.target_bdap ==
|
|
72
|
+
int_bdap = self.target_bdap == "INTE"
|
|
64
73
|
|
|
65
74
|
# Look for the input queries
|
|
66
75
|
input_queries = self.context.sequence.effective_inputs(
|
|
67
|
-
role=
|
|
68
|
-
kind=
|
|
76
|
+
role="Query",
|
|
77
|
+
kind="bdap_query",
|
|
69
78
|
)
|
|
70
79
|
|
|
71
80
|
rc_all = True
|
|
72
81
|
|
|
73
82
|
for input_query in input_queries:
|
|
74
83
|
for term in [Time(t) for t in footprints.util.rangex(self.terms)]:
|
|
75
|
-
|
|
76
84
|
# Launch each input queries in a dedicated file
|
|
77
85
|
# (to check that the files do not overwrite each other)
|
|
78
86
|
query_file = input_query.rh.container.abspath
|
|
79
|
-
local_directory =
|
|
87
|
+
local_directory = "_".join(
|
|
88
|
+
[query_file, self.date.ymdhms, term.fmtraw]
|
|
89
|
+
)
|
|
80
90
|
|
|
81
91
|
with self.system.cdcontext(local_directory, create=True):
|
|
82
92
|
# Determine the command to be launched
|
|
83
|
-
actual_command = BDAPrequest_actual_command(
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
93
|
+
actual_command = BDAPrequest_actual_command(
|
|
94
|
+
command=self.command,
|
|
95
|
+
date=self.date,
|
|
96
|
+
term=term,
|
|
97
|
+
query=query_file,
|
|
98
|
+
int_extraenv=int_bdap,
|
|
99
|
+
)
|
|
100
|
+
logger.info(
|
|
101
|
+
" ".join(["BDAP extract command:", actual_command])
|
|
102
|
+
)
|
|
103
|
+
logger.info("The %s directive file contains:", query_file)
|
|
90
104
|
self.system.cat(query_file, output=False)
|
|
91
105
|
# Launch the BDAP request
|
|
92
|
-
rc = self.system.spawn(
|
|
106
|
+
rc = self.system.spawn(
|
|
107
|
+
[
|
|
108
|
+
actual_command,
|
|
109
|
+
],
|
|
110
|
+
shell=True,
|
|
111
|
+
output=False,
|
|
112
|
+
fatal=False,
|
|
113
|
+
)
|
|
93
114
|
|
|
94
115
|
if not rc:
|
|
95
|
-
logger.exception(
|
|
96
|
-
|
|
116
|
+
logger.exception(
|
|
117
|
+
"Problem during the BDAP request of %s.", query_file
|
|
118
|
+
)
|
|
119
|
+
if self.system.path.isfile("DIAG_BDAP"):
|
|
97
120
|
raise BDAPRequestConfigurationError
|
|
98
121
|
else:
|
|
99
122
|
raise BDAPGetError
|
|
@@ -101,7 +124,7 @@ class GetBDAPResource(AlgoComponent):
|
|
|
101
124
|
rc_all = rc_all and rc
|
|
102
125
|
|
|
103
126
|
if not rc_all:
|
|
104
|
-
logger.exception(
|
|
127
|
+
logger.exception("Problem during the BDAP request.")
|
|
105
128
|
|
|
106
129
|
return rc_all
|
|
107
130
|
|
|
@@ -110,22 +133,22 @@ class GetBDMPResource(AlgoComponent):
|
|
|
110
133
|
"""Algo component to get BDMP resources considering a BDMP query file."""
|
|
111
134
|
|
|
112
135
|
_footprint = dict(
|
|
113
|
-
info
|
|
114
|
-
attr
|
|
115
|
-
kind
|
|
116
|
-
values
|
|
136
|
+
info="Algo component to get BDMP files.",
|
|
137
|
+
attr=dict(
|
|
138
|
+
kind=dict(
|
|
139
|
+
values=["get_bdmp"],
|
|
117
140
|
),
|
|
118
|
-
target_bdmp
|
|
119
|
-
default
|
|
120
|
-
optional
|
|
121
|
-
values
|
|
141
|
+
target_bdmp=dict(
|
|
142
|
+
default="OPER",
|
|
143
|
+
optional=True,
|
|
144
|
+
values=["OPER", "INTE", "ARCH"],
|
|
122
145
|
),
|
|
123
|
-
command
|
|
124
|
-
default
|
|
125
|
-
optional
|
|
126
|
-
values
|
|
146
|
+
command=dict(
|
|
147
|
+
default="bdmp_lecture",
|
|
148
|
+
optional=True,
|
|
149
|
+
values=["bdmp_lecture", "bdmp_lecture_pg", "bdmp_lecture_ora"],
|
|
127
150
|
),
|
|
128
|
-
)
|
|
151
|
+
),
|
|
129
152
|
)
|
|
130
153
|
|
|
131
154
|
def execute_single(self, rh, opts):
|
|
@@ -137,40 +160,50 @@ class GetBDMPResource(AlgoComponent):
|
|
|
137
160
|
|
|
138
161
|
# Look for the input queries
|
|
139
162
|
input_queries = self.context.sequence.effective_inputs(
|
|
140
|
-
role=
|
|
141
|
-
kind=
|
|
163
|
+
role="Query",
|
|
164
|
+
kind="bdmp_query",
|
|
142
165
|
)
|
|
143
166
|
|
|
144
167
|
rc_all = True
|
|
145
168
|
|
|
146
169
|
for input_query in input_queries:
|
|
147
|
-
|
|
148
170
|
# Get information on the query file
|
|
149
171
|
query_file = input_query.rh.container.abspath
|
|
150
|
-
logger.info(
|
|
172
|
+
logger.info("The %s directive file contains:", query_file)
|
|
151
173
|
self.system.cat(query_file, output=False)
|
|
152
174
|
|
|
153
175
|
# Construct the name of the temporary directory
|
|
154
|
-
local_directory =
|
|
176
|
+
local_directory = "_".join([query_file, "extract"])
|
|
155
177
|
|
|
156
178
|
# Determine the command to be launched
|
|
157
|
-
actual_command = BDMPrequest_actual_command(
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
179
|
+
actual_command = BDMPrequest_actual_command(
|
|
180
|
+
command=self.command,
|
|
181
|
+
query=query_file,
|
|
182
|
+
target_bdmp=self.target_bdmp,
|
|
183
|
+
)
|
|
184
|
+
logger.info(" ".join(["BDMP extract command:", actual_command]))
|
|
161
185
|
|
|
162
186
|
# Launch the BDMP request
|
|
163
187
|
with self.system.cdcontext(local_directory, create=True):
|
|
164
|
-
rc = self.system.spawn(
|
|
188
|
+
rc = self.system.spawn(
|
|
189
|
+
[
|
|
190
|
+
actual_command,
|
|
191
|
+
],
|
|
192
|
+
shell=True,
|
|
193
|
+
output=False,
|
|
194
|
+
fatal=False,
|
|
195
|
+
)
|
|
165
196
|
|
|
166
197
|
if not rc:
|
|
167
|
-
logger.exception(
|
|
198
|
+
logger.exception(
|
|
199
|
+
"Problem during the BDMP request of %s.", query_file
|
|
200
|
+
)
|
|
168
201
|
raise BDMPGetError
|
|
169
202
|
|
|
170
203
|
rc_all = rc_all and rc
|
|
171
204
|
|
|
172
205
|
if not rc_all:
|
|
173
|
-
logger.exception(
|
|
206
|
+
logger.exception("Problem during the BDMP request.")
|
|
174
207
|
|
|
175
208
|
return rc_all
|
|
176
209
|
|
|
@@ -179,22 +212,22 @@ class GetBDCPResource(AlgoComponent):
|
|
|
179
212
|
"""Algo component to get BDCP resources considering a BDCP query file."""
|
|
180
213
|
|
|
181
214
|
_footprint = dict(
|
|
182
|
-
info
|
|
183
|
-
attr
|
|
184
|
-
kind
|
|
185
|
-
values
|
|
215
|
+
info="Algo component to get BDCP files.",
|
|
216
|
+
attr=dict(
|
|
217
|
+
kind=dict(
|
|
218
|
+
values=["get_bdcp"],
|
|
186
219
|
),
|
|
187
|
-
target_bdcp
|
|
188
|
-
default
|
|
189
|
-
optional
|
|
190
|
-
values
|
|
220
|
+
target_bdcp=dict(
|
|
221
|
+
default="OPER",
|
|
222
|
+
optional=True,
|
|
223
|
+
values=["OPER"],
|
|
191
224
|
),
|
|
192
|
-
command
|
|
193
|
-
default
|
|
194
|
-
optional
|
|
195
|
-
values
|
|
225
|
+
command=dict(
|
|
226
|
+
default="extraction_directives",
|
|
227
|
+
optional=True,
|
|
228
|
+
values=["extraction_directives"],
|
|
196
229
|
),
|
|
197
|
-
)
|
|
230
|
+
),
|
|
198
231
|
)
|
|
199
232
|
|
|
200
233
|
def execute_single(self, rh, opts):
|
|
@@ -206,45 +239,55 @@ class GetBDCPResource(AlgoComponent):
|
|
|
206
239
|
|
|
207
240
|
# Look for the input queries
|
|
208
241
|
input_queries = self.context.sequence.effective_inputs(
|
|
209
|
-
role=
|
|
210
|
-
kind=
|
|
242
|
+
role="Query",
|
|
243
|
+
kind="bdcp_query",
|
|
211
244
|
)
|
|
212
245
|
|
|
213
246
|
rc_all = True
|
|
214
247
|
|
|
215
248
|
for input_query in input_queries:
|
|
216
|
-
|
|
217
249
|
# Get information on the query file
|
|
218
250
|
query_file = input_query.rh.container.abspath
|
|
219
|
-
logger.info(
|
|
251
|
+
logger.info("The %s directive file contains:", query_file)
|
|
220
252
|
self.system.cat(query_file, output=False)
|
|
221
253
|
|
|
222
254
|
# Construct the name of the output and log files
|
|
223
|
-
local_directory =
|
|
224
|
-
output_file =
|
|
225
|
-
output_log =
|
|
255
|
+
local_directory = "_".join([query_file, "extract"])
|
|
256
|
+
output_file = "extract.out"
|
|
257
|
+
output_log = "extract.out.diag"
|
|
226
258
|
|
|
227
259
|
# Determine the command to be launched
|
|
228
|
-
actual_command = BDCPrequest_actual_command(
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
260
|
+
actual_command = BDCPrequest_actual_command(
|
|
261
|
+
command=self.command,
|
|
262
|
+
query_file=query_file,
|
|
263
|
+
output_file=output_file,
|
|
264
|
+
)
|
|
265
|
+
logger.info(" ".join(["BDMP extract command:", actual_command]))
|
|
232
266
|
|
|
233
267
|
# Launch the BDCP request
|
|
234
268
|
with self.system.cdcontext(local_directory, create=True):
|
|
235
|
-
rc = self.system.spawn(
|
|
269
|
+
rc = self.system.spawn(
|
|
270
|
+
[
|
|
271
|
+
actual_command,
|
|
272
|
+
],
|
|
273
|
+
shell=True,
|
|
274
|
+
output=False,
|
|
275
|
+
fatal=False,
|
|
276
|
+
)
|
|
236
277
|
# Cat the log file
|
|
237
|
-
logger.info(
|
|
278
|
+
logger.info("Content of the log file:")
|
|
238
279
|
self.system.cat(output_log, output=False)
|
|
239
280
|
|
|
240
281
|
if not rc:
|
|
241
|
-
logger.exception(
|
|
282
|
+
logger.exception(
|
|
283
|
+
"Problem during the BDCP request of %s.", query_file
|
|
284
|
+
)
|
|
242
285
|
raise BDCPGetError
|
|
243
286
|
|
|
244
287
|
rc_all = rc_all and rc
|
|
245
288
|
|
|
246
289
|
if not rc_all:
|
|
247
|
-
logger.exception(
|
|
290
|
+
logger.exception("Problem during the BDCP request.")
|
|
248
291
|
|
|
249
292
|
return rc_all
|
|
250
293
|
|
|
@@ -253,47 +296,51 @@ class GetBDCPResource(AlgoComponent):
|
|
|
253
296
|
class _GetBDMDecoMixin(AlgoComponentDecoMixin):
|
|
254
297
|
"""Class variables and methods usefull for BDM extractions."""
|
|
255
298
|
|
|
256
|
-
_MIXIN_EXTRA_FOOTPRINTS = [
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
299
|
+
_MIXIN_EXTRA_FOOTPRINTS = [
|
|
300
|
+
footprints.Footprint(
|
|
301
|
+
attr=dict(
|
|
302
|
+
date=a_date,
|
|
303
|
+
pwd_file=dict(
|
|
304
|
+
default="/usr/local/sopra/neons_pwd",
|
|
305
|
+
values=["/usr/local/sopra/neons_pwd"],
|
|
306
|
+
optional=True,
|
|
307
|
+
),
|
|
308
|
+
fatal=dict(
|
|
309
|
+
type=bool,
|
|
310
|
+
default=False,
|
|
311
|
+
values=[True, False],
|
|
312
|
+
optional=True,
|
|
313
|
+
),
|
|
314
|
+
defaut_queryname=dict(
|
|
315
|
+
default="vortexdefault_query_name",
|
|
316
|
+
doc_visibility=footprints.doc.visibility.GURU,
|
|
317
|
+
optional=True,
|
|
318
|
+
),
|
|
274
319
|
)
|
|
275
320
|
)
|
|
276
|
-
|
|
321
|
+
]
|
|
277
322
|
|
|
278
323
|
def _verbose_env_export(self, varname, value):
|
|
279
324
|
self.env.setvar(varname, value)
|
|
280
|
-
logger.info(
|
|
325
|
+
logger.info(
|
|
326
|
+
"Setting environment variable %s = %s", varname, str(value)
|
|
327
|
+
)
|
|
281
328
|
|
|
282
329
|
def _prepare_commons(self, rh, opts):
|
|
283
330
|
"""
|
|
284
331
|
Prepare the launch of the script
|
|
285
332
|
"""
|
|
286
333
|
# Some exports to be done
|
|
287
|
-
self._verbose_env_export(
|
|
288
|
-
self._verbose_env_export(
|
|
334
|
+
self._verbose_env_export("PWD_FILE", self.pwd_file)
|
|
335
|
+
self._verbose_env_export("DMT_DATE_PIVOT", self.date.ymdhms)
|
|
289
336
|
|
|
290
|
-
_MIXIN_PREPARE_HOOKS = (_prepare_commons,
|
|
337
|
+
_MIXIN_PREPARE_HOOKS = (_prepare_commons,)
|
|
291
338
|
|
|
292
339
|
def _spawn_command_options_extend(self, prev):
|
|
293
|
-
prev[
|
|
340
|
+
prev["query"] = self.defaut_queryname
|
|
294
341
|
return prev
|
|
295
342
|
|
|
296
|
-
_MIXIN_CLI_OPTS_EXTEND = (_spawn_command_options_extend,
|
|
343
|
+
_MIXIN_CLI_OPTS_EXTEND = (_spawn_command_options_extend,)
|
|
297
344
|
|
|
298
345
|
def _execute_commons(self, rh, opts):
|
|
299
346
|
"""Launch the BDM request(s).
|
|
@@ -317,25 +364,34 @@ class _GetBDMDecoMixin(AlgoComponentDecoMixin):
|
|
|
317
364
|
# (to check that the files do not overwrite one another)
|
|
318
365
|
with self.system.cdcontext(loc_dir, create=True):
|
|
319
366
|
# Make the links needed
|
|
320
|
-
self.system.symlink(query_abspath,
|
|
321
|
-
self.defaut_queryname)
|
|
367
|
+
self.system.symlink(query_abspath, self.defaut_queryname)
|
|
322
368
|
# Cat the query content
|
|
323
|
-
logger.info(
|
|
369
|
+
logger.info("The %s directive file contains:", query_filename)
|
|
324
370
|
self.system.cat(self.defaut_queryname, output=False)
|
|
325
371
|
# Launch the BDM request and catch
|
|
326
372
|
try:
|
|
327
|
-
super(self.mixin_execute_companion(), self).execute(
|
|
373
|
+
super(self.mixin_execute_companion(), self).execute(
|
|
374
|
+
rh, opts
|
|
375
|
+
)
|
|
328
376
|
except ExecutionError:
|
|
329
377
|
rc_all = False
|
|
330
|
-
logger.error(
|
|
378
|
+
logger.error(
|
|
379
|
+
"Problem during the BDM request of %s.", query_filename
|
|
380
|
+
)
|
|
331
381
|
if self.fatal:
|
|
332
|
-
raise BDMGetError(
|
|
382
|
+
raise BDMGetError(
|
|
383
|
+
"Problem during the BDM request of {}.".format(
|
|
384
|
+
query_filename
|
|
385
|
+
)
|
|
386
|
+
)
|
|
333
387
|
# Delete the links
|
|
334
388
|
self.system.rm(self.defaut_queryname)
|
|
335
389
|
self.system.dir(output=False, fatal=False)
|
|
336
390
|
|
|
337
391
|
if not rc_all:
|
|
338
|
-
logger.error(
|
|
392
|
+
logger.error(
|
|
393
|
+
"At least one of the BDM request failed. Please check the logs above."
|
|
394
|
+
)
|
|
339
395
|
|
|
340
396
|
_MIXIN_EXECUTE_OVERWRITE = _execute_commons
|
|
341
397
|
|
|
@@ -345,15 +401,17 @@ class _GetBDMDecoMixin(AlgoComponentDecoMixin):
|
|
|
345
401
|
# BATORMAP concatenation
|
|
346
402
|
# Determine the name of the batormap produced by the execution in the different directories
|
|
347
403
|
input_queries = self._get_input_queries()
|
|
348
|
-
local_dir = [
|
|
349
|
-
|
|
404
|
+
local_dir = [
|
|
405
|
+
self._local_directory(input_query.rh.container.filename)
|
|
406
|
+
for input_query in input_queries
|
|
407
|
+
]
|
|
350
408
|
temp_files = []
|
|
351
409
|
for directory in local_dir:
|
|
352
|
-
glob_files = self.system.glob(
|
|
410
|
+
glob_files = self.system.glob("/".join([directory, "*batormap*"]))
|
|
353
411
|
for element in glob_files:
|
|
354
412
|
temp_files.append(element)
|
|
355
413
|
# Initialize the resulting batormap file
|
|
356
|
-
obsmap_filename =
|
|
414
|
+
obsmap_filename = "_".join(["OBSMAP", self.date.ymdhms])
|
|
357
415
|
content = []
|
|
358
416
|
# Check if a batormap is already present in the directory (from previous extract)
|
|
359
417
|
if self.system.path.isfile(obsmap_filename):
|
|
@@ -370,70 +428,74 @@ class _GetBDMDecoMixin(AlgoComponentDecoMixin):
|
|
|
370
428
|
out_container = footprints.proxy.container(local=obsmap_filename)
|
|
371
429
|
out_content.rewrite(out_container)
|
|
372
430
|
out_container.close()
|
|
373
|
-
logger.info(
|
|
431
|
+
logger.info("Content of the global batormap:")
|
|
374
432
|
self.system.cat(out_container.filename, output=False)
|
|
375
433
|
|
|
376
434
|
# Listing concatenation
|
|
377
435
|
# Initialize the resulting file
|
|
378
|
-
listing_filename =
|
|
436
|
+
listing_filename = "OULOUTPUT"
|
|
379
437
|
# Determine the name of the listing files produced by the execution
|
|
380
438
|
listing_files = []
|
|
381
439
|
for directory in local_dir:
|
|
382
|
-
glob_files = self.system.glob(
|
|
440
|
+
glob_files = self.system.glob(
|
|
441
|
+
"/".join([directory, listing_filename])
|
|
442
|
+
)
|
|
383
443
|
for element in glob_files:
|
|
384
444
|
listing_files.append(element)
|
|
385
445
|
# Check if a listing is already present and has to be merged with the other
|
|
386
446
|
if self.system.path.isfile(listing_filename):
|
|
387
|
-
temp_listing =
|
|
447
|
+
temp_listing = ".".join([listing_filename, "tmp"])
|
|
388
448
|
self.system.mv(listing_filename, temp_listing)
|
|
389
449
|
listing_files.append(temp_listing)
|
|
390
450
|
# Concatenate the listings
|
|
391
451
|
self.system.cat(*listing_files, output=listing_filename)
|
|
392
452
|
|
|
393
|
-
_MIXIN_POSTFIX_HOOKS = (_postfix_commons,
|
|
453
|
+
_MIXIN_POSTFIX_HOOKS = (_postfix_commons,)
|
|
394
454
|
|
|
395
455
|
|
|
396
456
|
class GetBDMBufr(Expresso, _GetBDMDecoMixin):
|
|
397
457
|
"""Algo component to get BDM resources considering a BDM query file."""
|
|
398
458
|
|
|
399
459
|
_footprint = dict(
|
|
400
|
-
info
|
|
401
|
-
attr
|
|
402
|
-
kind
|
|
403
|
-
values
|
|
460
|
+
info="Algo component to get BDM BUFR.",
|
|
461
|
+
attr=dict(
|
|
462
|
+
kind=dict(
|
|
463
|
+
values=["get_bdm_bufr"],
|
|
404
464
|
),
|
|
405
|
-
db_file_bdm
|
|
406
|
-
default
|
|
407
|
-
values
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
465
|
+
db_file_bdm=dict(
|
|
466
|
+
default="/usr/local/sopra/neons_db_bdm",
|
|
467
|
+
values=[
|
|
468
|
+
"/usr/local/sopra/neons_db_bdm",
|
|
469
|
+
"/usr/local/sopra/neons_db_bdm.archi",
|
|
470
|
+
"/usr/local/sopra/neons_db_bdm.intgr",
|
|
471
|
+
],
|
|
472
|
+
optional=True,
|
|
411
473
|
),
|
|
412
|
-
extra_env_opt
|
|
413
|
-
values
|
|
414
|
-
default
|
|
415
|
-
optional
|
|
474
|
+
extra_env_opt=dict(
|
|
475
|
+
values=["RECHERCHE", "OPERATIONNEL", "OPER"],
|
|
476
|
+
default="OPER",
|
|
477
|
+
optional=True,
|
|
416
478
|
),
|
|
417
|
-
shlib_path
|
|
418
|
-
default
|
|
419
|
-
optional
|
|
479
|
+
shlib_path=dict(
|
|
480
|
+
default="/usr/local/lib",
|
|
481
|
+
optional=True,
|
|
420
482
|
),
|
|
421
|
-
interpreter
|
|
422
|
-
default
|
|
423
|
-
values
|
|
424
|
-
optional
|
|
483
|
+
interpreter=dict(
|
|
484
|
+
default="awk",
|
|
485
|
+
values=["awk"],
|
|
486
|
+
optional=True,
|
|
425
487
|
),
|
|
426
|
-
)
|
|
488
|
+
),
|
|
427
489
|
)
|
|
428
490
|
|
|
429
491
|
def _local_directory(self, query_filename):
|
|
430
|
-
return
|
|
492
|
+
return "_".join(["BUFR", query_filename, self.date.ymdhms])
|
|
431
493
|
|
|
432
494
|
def _get_input_queries(self):
|
|
433
495
|
"""Returns the list of queries to process."""
|
|
434
496
|
return self.context.sequence.effective_inputs(
|
|
435
|
-
role=
|
|
436
|
-
kind=
|
|
497
|
+
role="Query",
|
|
498
|
+
kind="bdm_query",
|
|
437
499
|
)
|
|
438
500
|
|
|
439
501
|
def prepare(self, rh, opts):
|
|
@@ -444,45 +506,51 @@ class GetBDMBufr(Expresso, _GetBDMDecoMixin):
|
|
|
444
506
|
super().prepare(rh, opts)
|
|
445
507
|
|
|
446
508
|
# Some exports to be done
|
|
447
|
-
self._verbose_env_export(
|
|
448
|
-
self._verbose_env_export(
|
|
449
|
-
self._verbose_env_export(
|
|
509
|
+
self._verbose_env_export("EXTR_ENV", self.extra_env_opt)
|
|
510
|
+
self._verbose_env_export("DB_FILE_BDM", self.db_file_bdm)
|
|
511
|
+
self._verbose_env_export(
|
|
512
|
+
"SHLIB_PATH", ":".join(["$SHLIB_PATH", self.shlib_path])
|
|
513
|
+
)
|
|
450
514
|
|
|
451
515
|
# Check if query files are present
|
|
452
516
|
input_queries = self._get_input_queries()
|
|
453
517
|
if len(input_queries) < 1:
|
|
454
|
-
logger.exception(
|
|
455
|
-
|
|
518
|
+
logger.exception(
|
|
519
|
+
"No query file found for the BDM extraction. Stop."
|
|
520
|
+
)
|
|
521
|
+
raise BDMRequestConfigurationError(
|
|
522
|
+
"No query file found for the BDM extraction"
|
|
523
|
+
)
|
|
456
524
|
|
|
457
525
|
|
|
458
526
|
class GetBDMOulan(BlindRun, _GetBDMDecoMixin):
|
|
459
527
|
"""Algo component to get BDM files using Oulan."""
|
|
460
528
|
|
|
461
529
|
_footprint = dict(
|
|
462
|
-
info
|
|
463
|
-
attr
|
|
464
|
-
kind
|
|
465
|
-
values
|
|
530
|
+
info="Algo component to get BDM files using Oulan.",
|
|
531
|
+
attr=dict(
|
|
532
|
+
kind=dict(
|
|
533
|
+
values=["get_bdm_oulan"],
|
|
466
534
|
),
|
|
467
|
-
db_file
|
|
468
|
-
default
|
|
469
|
-
values
|
|
470
|
-
optional
|
|
535
|
+
db_file=dict(
|
|
536
|
+
default="/usr/local/sopra/neons_db",
|
|
537
|
+
values=["/usr/local/sopra/neons_db"],
|
|
538
|
+
optional=True,
|
|
471
539
|
),
|
|
472
|
-
defaut_queryname
|
|
473
|
-
default
|
|
540
|
+
defaut_queryname=dict(
|
|
541
|
+
default="NAMELIST",
|
|
474
542
|
),
|
|
475
|
-
)
|
|
543
|
+
),
|
|
476
544
|
)
|
|
477
545
|
|
|
478
546
|
def _local_directory(self, query_filename):
|
|
479
|
-
return
|
|
547
|
+
return "_".join(["Oulan", query_filename, self.date.ymdhms])
|
|
480
548
|
|
|
481
549
|
def _get_input_queries(self):
|
|
482
550
|
"""Returns the list of namelists to process."""
|
|
483
551
|
return self.context.sequence.effective_inputs(
|
|
484
|
-
role=
|
|
485
|
-
kind=
|
|
552
|
+
role="NamelistOulan",
|
|
553
|
+
kind="namutil",
|
|
486
554
|
)
|
|
487
555
|
|
|
488
556
|
def prepare(self, rh, opts):
|
|
@@ -491,40 +559,36 @@ class GetBDMOulan(BlindRun, _GetBDMDecoMixin):
|
|
|
491
559
|
super().prepare(rh, opts)
|
|
492
560
|
|
|
493
561
|
# Export additional variables
|
|
494
|
-
self._verbose_env_export(
|
|
562
|
+
self._verbose_env_export("DB_FILE", self.db_file)
|
|
495
563
|
|
|
496
564
|
# Check if namelists are present
|
|
497
565
|
input_namelists = self._get_input_queries()
|
|
498
566
|
if len(input_namelists) < 1:
|
|
499
|
-
logger.error(
|
|
500
|
-
raise BDMError(
|
|
567
|
+
logger.error("No Oulan namelist found. Stop.")
|
|
568
|
+
raise BDMError("No Oulan namelist found.")
|
|
501
569
|
|
|
502
570
|
|
|
503
571
|
class GetMarsResource(AlgoComponent):
|
|
504
572
|
"""AlgoComponent to get Mars resources using a Mars query file"""
|
|
505
573
|
|
|
506
574
|
_footprint = dict(
|
|
507
|
-
info
|
|
508
|
-
attr
|
|
509
|
-
kind
|
|
510
|
-
values
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
substitutions = dict(
|
|
514
|
-
info = "A dictionary of values to be substituted",
|
|
515
|
-
type = footprints.stdtypes.FPDict,
|
|
516
|
-
default = footprints.stdtypes.FPDict(),
|
|
517
|
-
optional = True
|
|
575
|
+
info="AlgoComponent to get a Mars resource",
|
|
576
|
+
attr=dict(
|
|
577
|
+
kind=dict(
|
|
578
|
+
values=[
|
|
579
|
+
"get_mars",
|
|
580
|
+
]
|
|
518
581
|
),
|
|
519
|
-
|
|
520
|
-
|
|
582
|
+
date=a_date,
|
|
583
|
+
substitutions=dict(
|
|
584
|
+
info="A dictionary of values to be substituted",
|
|
585
|
+
type=footprints.stdtypes.FPDict,
|
|
586
|
+
default=footprints.stdtypes.FPDict(),
|
|
587
|
+
optional=True,
|
|
521
588
|
),
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
optional = True
|
|
526
|
-
)
|
|
527
|
-
)
|
|
589
|
+
command=dict(optional=True),
|
|
590
|
+
fatal=dict(type=bool, default=True, optional=True),
|
|
591
|
+
),
|
|
528
592
|
)
|
|
529
593
|
|
|
530
594
|
def execute(self, rh, opts):
|
|
@@ -535,17 +599,21 @@ class GetMarsResource(AlgoComponent):
|
|
|
535
599
|
"""
|
|
536
600
|
# Look for input queries
|
|
537
601
|
input_queries = self.context.sequence.effective_inputs(
|
|
538
|
-
role=
|
|
539
|
-
kind=
|
|
602
|
+
role="Query",
|
|
603
|
+
kind="mars_query",
|
|
540
604
|
)
|
|
541
605
|
if len(input_queries) < 1:
|
|
542
|
-
logger.exception(
|
|
543
|
-
|
|
606
|
+
logger.exception(
|
|
607
|
+
"No query file found for the Mars extraction. Stop."
|
|
608
|
+
)
|
|
609
|
+
raise MarsGetError("No query file found for the Mars extraction")
|
|
544
610
|
|
|
545
611
|
rc_all = True
|
|
546
612
|
|
|
547
613
|
# Find the command to be launched
|
|
548
|
-
actual_command = findMarsExtractCommand(
|
|
614
|
+
actual_command = findMarsExtractCommand(
|
|
615
|
+
sh=self.system, command=self.command
|
|
616
|
+
)
|
|
549
617
|
|
|
550
618
|
# Prepare the substitutions' dictionnary
|
|
551
619
|
dictkeyvalue = copy.deepcopy(self.substitutions)
|
|
@@ -563,17 +631,30 @@ class GetMarsResource(AlgoComponent):
|
|
|
563
631
|
# Launch each input queries in a dedicated file
|
|
564
632
|
# (to check that the files do not overwrite each other)
|
|
565
633
|
query_file_path = input_query.rh.container.abspath
|
|
566
|
-
local_directory =
|
|
567
|
-
logger.info(
|
|
634
|
+
local_directory = "_".join([query_file_path, self.date.ymdhms])
|
|
635
|
+
logger.info(
|
|
636
|
+
"Here is the content of the query file %s (after substitution):",
|
|
637
|
+
query_file_path,
|
|
638
|
+
)
|
|
568
639
|
self.system.cat(query_file_path, output=False)
|
|
569
640
|
with self.system.cdcontext(local_directory, create=True):
|
|
570
641
|
# Launch the command
|
|
571
|
-
rc = callMarsExtract(
|
|
572
|
-
|
|
642
|
+
rc = callMarsExtract(
|
|
643
|
+
sh=self.system,
|
|
644
|
+
query_file=query_file_path,
|
|
645
|
+
fatal=self.fatal,
|
|
646
|
+
command=actual_command,
|
|
647
|
+
)
|
|
573
648
|
if not rc:
|
|
574
649
|
if self.fatal:
|
|
575
|
-
logger.error(
|
|
650
|
+
logger.error(
|
|
651
|
+
"Problem during the Mars request of %s",
|
|
652
|
+
query_file_path,
|
|
653
|
+
)
|
|
576
654
|
raise MarsGetError
|
|
577
655
|
else:
|
|
578
|
-
logger.warning(
|
|
656
|
+
logger.warning(
|
|
657
|
+
"Problem during the Mars request of %s",
|
|
658
|
+
query_file_path,
|
|
659
|
+
)
|
|
579
660
|
rc_all = rc_all and rc
|