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/ifsroot.py
CHANGED
|
@@ -5,11 +5,17 @@ Abstract base class for any AlgoComponent leveraging the Arpege/IFS code.
|
|
|
5
5
|
from bronx.fancies import loggers
|
|
6
6
|
import footprints
|
|
7
7
|
|
|
8
|
-
from vortex.algo.components import
|
|
8
|
+
from vortex.algo.components import (
|
|
9
|
+
Parallel,
|
|
10
|
+
ParallelIoServerMixin,
|
|
11
|
+
AlgoComponentError,
|
|
12
|
+
)
|
|
9
13
|
from vortex.syntax.stdattrs import model
|
|
10
14
|
from vortex.tools import grib
|
|
11
15
|
|
|
12
|
-
|
|
16
|
+
# footprints import
|
|
17
|
+
from . import ifsnaming as ifsnaming
|
|
18
|
+
|
|
13
19
|
from ..syntax.stdattrs import algo_member
|
|
14
20
|
from ..tools import satrad, drhook
|
|
15
21
|
|
|
@@ -19,105 +25,122 @@ __all__ = []
|
|
|
19
25
|
logger = loggers.getLogger(__name__)
|
|
20
26
|
|
|
21
27
|
|
|
22
|
-
class IFSParallel(
|
|
23
|
-
|
|
28
|
+
class IFSParallel(
|
|
29
|
+
Parallel,
|
|
30
|
+
ParallelIoServerMixin,
|
|
31
|
+
satrad.SatRadDecoMixin,
|
|
32
|
+
drhook.DrHookDecoMixin,
|
|
33
|
+
grib.EcGribDecoMixin,
|
|
34
|
+
):
|
|
24
35
|
"""Abstract IFSModel parallel algo components."""
|
|
25
36
|
|
|
26
37
|
_abstract = True
|
|
27
38
|
_footprint = [
|
|
28
|
-
model,
|
|
39
|
+
model,
|
|
40
|
+
algo_member,
|
|
29
41
|
dict(
|
|
30
|
-
info
|
|
31
|
-
attr
|
|
32
|
-
kind
|
|
33
|
-
info
|
|
34
|
-
default
|
|
35
|
-
doc_zorder
|
|
42
|
+
info="Abstract AlgoComponent for anything based on Arpege/IFS.",
|
|
43
|
+
attr=dict(
|
|
44
|
+
kind=dict(
|
|
45
|
+
info="The kind of processing we want the Arpege/IFS binary to perform.",
|
|
46
|
+
default="ifsrun",
|
|
47
|
+
doc_zorder=90,
|
|
36
48
|
),
|
|
37
|
-
model
|
|
38
|
-
values
|
|
39
|
-
|
|
49
|
+
model=dict(
|
|
50
|
+
values=[
|
|
51
|
+
"arpege",
|
|
52
|
+
"arp",
|
|
53
|
+
"arp_court",
|
|
54
|
+
"aladin",
|
|
55
|
+
"ald",
|
|
56
|
+
"arome",
|
|
57
|
+
"aro",
|
|
58
|
+
"aearp",
|
|
59
|
+
"pearp",
|
|
60
|
+
"ifs",
|
|
61
|
+
"alaro",
|
|
62
|
+
"harmoniearome",
|
|
63
|
+
]
|
|
40
64
|
),
|
|
41
|
-
ioname
|
|
42
|
-
default
|
|
65
|
+
ioname=dict(
|
|
66
|
+
default="nwpioserv",
|
|
43
67
|
),
|
|
44
|
-
binarysingle
|
|
45
|
-
default
|
|
68
|
+
binarysingle=dict(
|
|
69
|
+
default="basicnwp",
|
|
46
70
|
),
|
|
47
|
-
conf
|
|
48
|
-
info
|
|
49
|
-
type
|
|
50
|
-
optional
|
|
51
|
-
default
|
|
52
|
-
doc_visibility
|
|
71
|
+
conf=dict(
|
|
72
|
+
info="The configuration number given to Arpege/IFS.",
|
|
73
|
+
type=int,
|
|
74
|
+
optional=True,
|
|
75
|
+
default=1,
|
|
76
|
+
doc_visibility=footprints.doc.visibility.ADVANCED,
|
|
53
77
|
),
|
|
54
|
-
timescheme
|
|
55
|
-
info
|
|
56
|
-
optional
|
|
57
|
-
default
|
|
58
|
-
values
|
|
59
|
-
remap
|
|
60
|
-
|
|
61
|
-
semilag = 'sli'
|
|
62
|
-
),
|
|
63
|
-
doc_visibility = footprints.doc.visibility.ADVANCED,
|
|
78
|
+
timescheme=dict(
|
|
79
|
+
info="The timescheme that will be used by Arpege/IFS model.",
|
|
80
|
+
optional=True,
|
|
81
|
+
default="sli",
|
|
82
|
+
values=["eul", "eulerian", "sli", "semilag"],
|
|
83
|
+
remap=dict(eulerian="eul", semilag="sli"),
|
|
84
|
+
doc_visibility=footprints.doc.visibility.ADVANCED,
|
|
64
85
|
),
|
|
65
|
-
timestep
|
|
66
|
-
info
|
|
67
|
-
type
|
|
68
|
-
optional
|
|
69
|
-
default
|
|
86
|
+
timestep=dict(
|
|
87
|
+
info="The timestep of the Arpege/IFS model.",
|
|
88
|
+
type=float,
|
|
89
|
+
optional=True,
|
|
90
|
+
default=600.0,
|
|
70
91
|
),
|
|
71
|
-
fcterm
|
|
72
|
-
info
|
|
73
|
-
type
|
|
74
|
-
optional
|
|
75
|
-
default
|
|
92
|
+
fcterm=dict(
|
|
93
|
+
info="The forecast term of the Arpege/IFS model.",
|
|
94
|
+
type=int,
|
|
95
|
+
optional=True,
|
|
96
|
+
default=0,
|
|
76
97
|
),
|
|
77
|
-
fcunit
|
|
78
|
-
info
|
|
79
|
-
optional
|
|
80
|
-
default
|
|
81
|
-
values
|
|
82
|
-
remap
|
|
83
|
-
hour
|
|
84
|
-
step
|
|
85
|
-
timestep
|
|
86
|
-
)
|
|
98
|
+
fcunit=dict(
|
|
99
|
+
info="The unit used in the *fcterm* attribute.",
|
|
100
|
+
optional=True,
|
|
101
|
+
default="h",
|
|
102
|
+
values=["h", "hour", "t", "step", "timestep"],
|
|
103
|
+
remap=dict(
|
|
104
|
+
hour="h",
|
|
105
|
+
step="t",
|
|
106
|
+
timestep="t",
|
|
107
|
+
),
|
|
87
108
|
),
|
|
88
|
-
xpname
|
|
89
|
-
info
|
|
90
|
-
optional
|
|
91
|
-
default
|
|
92
|
-
doc_visibility
|
|
109
|
+
xpname=dict(
|
|
110
|
+
info="The default labelling of files used in Arpege/IFS model.",
|
|
111
|
+
optional=True,
|
|
112
|
+
default="XPVT",
|
|
113
|
+
doc_visibility=footprints.doc.visibility.ADVANCED,
|
|
93
114
|
),
|
|
94
|
-
)
|
|
95
|
-
)
|
|
115
|
+
),
|
|
116
|
+
),
|
|
96
117
|
]
|
|
97
118
|
|
|
98
119
|
def fstag(self):
|
|
99
120
|
"""Extend default tag with ``kind`` value."""
|
|
100
|
-
return super().fstag() +
|
|
121
|
+
return super().fstag() + "." + self.kind
|
|
101
122
|
|
|
102
123
|
def valid_executable(self, rh):
|
|
103
124
|
"""Be sure that the specifed executable is ifsmodel compatible."""
|
|
104
125
|
valid = super().valid_executable(rh)
|
|
105
126
|
try:
|
|
106
|
-
return valid and bool(rh.resource.realkind ==
|
|
127
|
+
return valid and bool(rh.resource.realkind == "ifsmodel")
|
|
107
128
|
except (ValueError, TypeError):
|
|
108
129
|
return False
|
|
109
130
|
|
|
110
131
|
def spawn_hook(self):
|
|
111
132
|
"""Usually a good habit to dump the fort.4 namelist."""
|
|
112
133
|
super().spawn_hook()
|
|
113
|
-
if self.system.path.exists(
|
|
114
|
-
self.system.subtitle(
|
|
115
|
-
|
|
134
|
+
if self.system.path.exists("fort.4"):
|
|
135
|
+
self.system.subtitle(
|
|
136
|
+
"{:s} : dump namelist <fort.4>".format(self.realkind)
|
|
137
|
+
)
|
|
138
|
+
self.system.cat("fort.4", output=False)
|
|
116
139
|
|
|
117
140
|
def spawn_command_options(self):
|
|
118
141
|
"""Dictionary provided for command line factory."""
|
|
119
142
|
return dict(
|
|
120
|
-
name=(self.xpname +
|
|
143
|
+
name=(self.xpname + "xxxx")[:4].upper(),
|
|
121
144
|
conf=self.conf,
|
|
122
145
|
timescheme=self.timescheme,
|
|
123
146
|
timestep=self.timestep,
|
|
@@ -133,19 +156,18 @@ class IFSParallel(Parallel, ParallelIoServerMixin,
|
|
|
133
156
|
:param actualfmt: The format of the target file.
|
|
134
157
|
:param dict kwargs: Any argument you may see fit.
|
|
135
158
|
"""
|
|
136
|
-
nc_args = dict(model=self.model,
|
|
137
|
-
conf=self.conf,
|
|
138
|
-
xpname=self.xpname)
|
|
159
|
+
nc_args = dict(model=self.model, conf=self.conf, xpname=self.xpname)
|
|
139
160
|
nc_args.update(kwargs)
|
|
140
|
-
nc = footprints.proxy.ifsnamingconv(
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
**nc_args)
|
|
161
|
+
nc = footprints.proxy.ifsnamingconv(
|
|
162
|
+
kind=kind, actualfmt=actualfmt, cycle=rh.resource.cycle, **nc_args
|
|
163
|
+
)
|
|
144
164
|
if nc is None:
|
|
145
165
|
raise AlgoComponentError("No IFSNamingConvention was found.")
|
|
146
166
|
return nc
|
|
147
167
|
|
|
148
|
-
def do_climfile_fixer(
|
|
168
|
+
def do_climfile_fixer(
|
|
169
|
+
self, rh, convkind, actualfmt=None, geo=None, **kwargs
|
|
170
|
+
):
|
|
149
171
|
"""Is it necessary to fix the climatology file ? (i.e link in the appropriate file).
|
|
150
172
|
|
|
151
173
|
:param rh: The binary's ResourceHandler.
|
|
@@ -155,16 +177,27 @@ class IFSParallel(Parallel, ParallelIoServerMixin,
|
|
|
155
177
|
:param dict kwargs: Any argument you may see fit (used to create and call
|
|
156
178
|
the IFSNamingConvention object.
|
|
157
179
|
"""
|
|
158
|
-
nc = self.naming_convention(
|
|
180
|
+
nc = self.naming_convention(
|
|
181
|
+
kind=convkind, rh=rh, actualfmt=actualfmt, **kwargs
|
|
182
|
+
)
|
|
159
183
|
nc_args = dict()
|
|
160
184
|
if geo:
|
|
161
|
-
nc_args[
|
|
185
|
+
nc_args["area"] = geo.area
|
|
162
186
|
nc_args.update(kwargs)
|
|
163
|
-
return not self.system.path.exists(nc(**
|
|
164
|
-
|
|
165
|
-
def climfile_fixer(
|
|
166
|
-
|
|
167
|
-
|
|
187
|
+
return not self.system.path.exists(nc(**nc_args))
|
|
188
|
+
|
|
189
|
+
def climfile_fixer(
|
|
190
|
+
self,
|
|
191
|
+
rh,
|
|
192
|
+
convkind,
|
|
193
|
+
month,
|
|
194
|
+
geo=None,
|
|
195
|
+
notgeo=None,
|
|
196
|
+
actualfmt=None,
|
|
197
|
+
inputrole=None,
|
|
198
|
+
inputkind=None,
|
|
199
|
+
**kwargs,
|
|
200
|
+
):
|
|
168
201
|
"""Fix the climatology files (by choosing the appropriate month, geometry, ...)
|
|
169
202
|
|
|
170
203
|
:param rh: The binary's ResourceHandler.
|
|
@@ -179,19 +212,25 @@ class IFSParallel(Parallel, ParallelIoServerMixin,
|
|
|
179
212
|
the IFSNamingConvention object).
|
|
180
213
|
"""
|
|
181
214
|
if geo is not None and notgeo is not None:
|
|
182
|
-
raise ValueError(
|
|
215
|
+
raise ValueError("*geo* and *notgeo* cannot be provided together.")
|
|
183
216
|
|
|
184
217
|
def check_month(actualrh):
|
|
185
|
-
return bool(
|
|
186
|
-
|
|
218
|
+
return bool(
|
|
219
|
+
hasattr(actualrh.resource, "month")
|
|
220
|
+
and actualrh.resource.month == month
|
|
221
|
+
)
|
|
187
222
|
|
|
188
223
|
def check_month_and_geo(actualrh):
|
|
189
|
-
return (
|
|
190
|
-
|
|
224
|
+
return (
|
|
225
|
+
check_month(actualrh)
|
|
226
|
+
and actualrh.resource.geometry.tag == geo.tag
|
|
227
|
+
)
|
|
191
228
|
|
|
192
229
|
def check_month_and_notgeo(actualrh):
|
|
193
|
-
return (
|
|
194
|
-
|
|
230
|
+
return (
|
|
231
|
+
check_month(actualrh)
|
|
232
|
+
and actualrh.resource.geometry.tag != notgeo.tag
|
|
233
|
+
)
|
|
195
234
|
|
|
196
235
|
if geo:
|
|
197
236
|
checker = check_month_and_geo
|
|
@@ -200,23 +239,41 @@ class IFSParallel(Parallel, ParallelIoServerMixin,
|
|
|
200
239
|
else:
|
|
201
240
|
checker = check_month
|
|
202
241
|
|
|
203
|
-
nc = self.naming_convention(
|
|
242
|
+
nc = self.naming_convention(
|
|
243
|
+
kind=convkind, rh=rh, actualfmt=actualfmt, **kwargs
|
|
244
|
+
)
|
|
204
245
|
nc_args = dict()
|
|
205
246
|
if geo:
|
|
206
|
-
nc_args[
|
|
247
|
+
nc_args["area"] = geo.area
|
|
207
248
|
nc_args.update(kwargs)
|
|
208
|
-
target_name = nc(**
|
|
249
|
+
target_name = nc(**nc_args)
|
|
209
250
|
|
|
210
251
|
self.system.remove(target_name)
|
|
211
252
|
|
|
212
|
-
logger.info(
|
|
213
|
-
|
|
214
|
-
|
|
253
|
+
logger.info(
|
|
254
|
+
"Linking in the %s file (%s) for month %s.",
|
|
255
|
+
convkind,
|
|
256
|
+
target_name,
|
|
257
|
+
month,
|
|
258
|
+
)
|
|
259
|
+
rc = self.setlink(
|
|
260
|
+
initrole=inputrole,
|
|
261
|
+
initkind=inputkind,
|
|
262
|
+
inittest=checker,
|
|
263
|
+
initname=target_name,
|
|
264
|
+
)
|
|
215
265
|
return target_name if rc else None
|
|
216
266
|
|
|
217
|
-
def all_localclim_fixer(
|
|
218
|
-
|
|
219
|
-
|
|
267
|
+
def all_localclim_fixer(
|
|
268
|
+
self,
|
|
269
|
+
rh,
|
|
270
|
+
month,
|
|
271
|
+
convkind="targetclim",
|
|
272
|
+
actualfmt=None,
|
|
273
|
+
inputrole=("LocalClim", "TargetClim", "BDAPClim"),
|
|
274
|
+
inputkind="clim_bdap",
|
|
275
|
+
**kwargs,
|
|
276
|
+
):
|
|
220
277
|
"""Fix all the local/BDAP climatology files (by choosing the appropriate month)
|
|
221
278
|
|
|
222
279
|
:param rh: The binary's ResourceHandler.
|
|
@@ -231,19 +288,33 @@ class IFSParallel(Parallel, ParallelIoServerMixin,
|
|
|
231
288
|
"""
|
|
232
289
|
|
|
233
290
|
def check_month(actualrh):
|
|
234
|
-
return bool(
|
|
235
|
-
|
|
291
|
+
return bool(
|
|
292
|
+
hasattr(actualrh.resource, "month")
|
|
293
|
+
and actualrh.resource.month == month
|
|
294
|
+
)
|
|
236
295
|
|
|
237
|
-
nc = self.naming_convention(
|
|
296
|
+
nc = self.naming_convention(
|
|
297
|
+
kind=convkind, rh=rh, actualfmt=actualfmt, **kwargs
|
|
298
|
+
)
|
|
238
299
|
dealtwith = list()
|
|
239
300
|
|
|
240
|
-
for tclimrh in [
|
|
241
|
-
|
|
242
|
-
|
|
301
|
+
for tclimrh in [
|
|
302
|
+
x.rh
|
|
303
|
+
for x in self.context.sequence.effective_inputs(
|
|
304
|
+
role=inputrole,
|
|
305
|
+
kind=inputkind,
|
|
306
|
+
)
|
|
307
|
+
if x.rh.resource.month == month
|
|
308
|
+
]:
|
|
243
309
|
thisclim = tclimrh.container.localpath()
|
|
244
310
|
thisname = nc(area=tclimrh.resource.geometry.area)
|
|
245
311
|
if thisclim != thisname:
|
|
246
|
-
logger.info(
|
|
312
|
+
logger.info(
|
|
313
|
+
"Linking in the %s to %s for month %s.",
|
|
314
|
+
thisclim,
|
|
315
|
+
thisname,
|
|
316
|
+
month,
|
|
317
|
+
)
|
|
247
318
|
self.system.symlink(thisclim, thisname)
|
|
248
319
|
dealtwith.append(thisname)
|
|
249
320
|
|
|
@@ -251,13 +322,17 @@ class IFSParallel(Parallel, ParallelIoServerMixin,
|
|
|
251
322
|
|
|
252
323
|
def find_namelists(self, opts=None):
|
|
253
324
|
"""Find any namelists candidates in actual context inputs."""
|
|
254
|
-
return [
|
|
255
|
-
|
|
325
|
+
return [
|
|
326
|
+
x.rh
|
|
327
|
+
for x in self.context.sequence.effective_inputs(
|
|
328
|
+
kind=("namelist", "namelistfp")
|
|
329
|
+
)
|
|
330
|
+
]
|
|
256
331
|
|
|
257
332
|
def _set_nam_macro(self, namcontents, namlocal, macro, value):
|
|
258
333
|
"""Set a namelist macro and log it!"""
|
|
259
334
|
namcontents.setmacro(macro, value)
|
|
260
|
-
logger.info(
|
|
335
|
+
logger.info("Setup macro %s=%s in %s", macro, str(value), namlocal)
|
|
261
336
|
|
|
262
337
|
def prepare_namelist_delta(self, rh, namcontents, namlocal):
|
|
263
338
|
"""Apply a namelist delta depending on the cycle of the binary."""
|
|
@@ -268,34 +343,47 @@ class IFSParallel(Parallel, ParallelIoServerMixin,
|
|
|
268
343
|
nam_updated = False
|
|
269
344
|
# For cy41 onward, replace some namelist macros with the command line
|
|
270
345
|
# arguments
|
|
271
|
-
if rh.resource.cycle >=
|
|
272
|
-
if
|
|
346
|
+
if rh.resource.cycle >= "cy41":
|
|
347
|
+
if "NAMARG" in namcontents:
|
|
273
348
|
opts_arg = self.spawn_command_options()
|
|
274
|
-
self._set_nam_macro(
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
self._set_nam_macro(
|
|
349
|
+
self._set_nam_macro(
|
|
350
|
+
namcontents, namlocal, "CEXP", opts_arg["name"]
|
|
351
|
+
)
|
|
352
|
+
self._set_nam_macro(
|
|
353
|
+
namcontents, namlocal, "TIMESTEP", opts_arg["timestep"]
|
|
354
|
+
)
|
|
355
|
+
fcstop = "{:s}{:d}".format(
|
|
356
|
+
opts_arg["fcunit"], opts_arg["fcterm"]
|
|
357
|
+
)
|
|
358
|
+
self._set_nam_macro(namcontents, namlocal, "FCSTOP", fcstop)
|
|
278
359
|
nam_updated = True
|
|
279
360
|
else:
|
|
280
|
-
logger.info(
|
|
361
|
+
logger.info("No NAMARG block in %s", namlocal)
|
|
281
362
|
|
|
282
363
|
if self.member is not None:
|
|
283
|
-
for macro_name in (
|
|
284
|
-
self._set_nam_macro(
|
|
364
|
+
for macro_name in ("MEMBER", "PERTURB"):
|
|
365
|
+
self._set_nam_macro(
|
|
366
|
+
namcontents, namlocal, macro_name, self.member
|
|
367
|
+
)
|
|
285
368
|
nam_updated = True
|
|
286
369
|
return nam_updated
|
|
287
370
|
|
|
288
371
|
def prepare_namelists(self, rh, opts=None):
|
|
289
372
|
"""Update each of the namelists."""
|
|
290
373
|
namcandidates = self.find_namelists(opts)
|
|
291
|
-
self.system.subtitle(
|
|
374
|
+
self.system.subtitle("Namelist candidates")
|
|
292
375
|
for nam in namcandidates:
|
|
293
376
|
nam.quickview()
|
|
294
377
|
for namrh in namcandidates:
|
|
295
378
|
namc = namrh.contents
|
|
296
|
-
if self.prepare_namelist_delta(
|
|
379
|
+
if self.prepare_namelist_delta(
|
|
380
|
+
rh, namc, namrh.container.actualpath()
|
|
381
|
+
):
|
|
297
382
|
if namc.dumps_needs_update:
|
|
298
|
-
logger.info(
|
|
383
|
+
logger.info(
|
|
384
|
+
"Rewritting the %s namelists file.",
|
|
385
|
+
namrh.container.actualpath(),
|
|
386
|
+
)
|
|
299
387
|
namc.rewrite(namrh.container)
|
|
300
388
|
|
|
301
389
|
def prepare(self, rh, opts):
|
|
@@ -306,6 +394,6 @@ class IFSParallel(Parallel, ParallelIoServerMixin,
|
|
|
306
394
|
|
|
307
395
|
def execute_single(self, rh, opts):
|
|
308
396
|
"""Standard IFS-Like execution parallel execution."""
|
|
309
|
-
if rh.resource.cycle <
|
|
310
|
-
self.system.ls(output=
|
|
397
|
+
if rh.resource.cycle < "cy46":
|
|
398
|
+
self.system.ls(output="dirlst")
|
|
311
399
|
super().execute_single(rh, opts)
|