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/data/obs.py
CHANGED
|
@@ -18,14 +18,16 @@ from vortex.syntax import stdattrs, stddeco
|
|
|
18
18
|
from ..syntax.stdattrs import gvar, GenvKey
|
|
19
19
|
|
|
20
20
|
#: Automatic export of Observations class
|
|
21
|
-
__all__ = [
|
|
21
|
+
__all__ = [
|
|
22
|
+
"Observations",
|
|
23
|
+
]
|
|
22
24
|
|
|
23
25
|
logger = loggers.getLogger(__name__)
|
|
24
26
|
|
|
25
27
|
|
|
26
|
-
@stddeco.namebuilding_insert(
|
|
27
|
-
@stddeco.namebuilding_insert(
|
|
28
|
-
@stddeco.namebuilding_insert(
|
|
28
|
+
@stddeco.namebuilding_insert("style", lambda s: "obs")
|
|
29
|
+
@stddeco.namebuilding_insert("stage", lambda s: s.stage)
|
|
30
|
+
@stddeco.namebuilding_insert("part", lambda s: s.part)
|
|
29
31
|
class Observations(GeoFlowResource):
|
|
30
32
|
"""
|
|
31
33
|
Abstract observation resource.
|
|
@@ -33,135 +35,176 @@ class Observations(GeoFlowResource):
|
|
|
33
35
|
|
|
34
36
|
_abstract = True
|
|
35
37
|
_footprint = dict(
|
|
36
|
-
info
|
|
37
|
-
attr
|
|
38
|
-
kind
|
|
39
|
-
values
|
|
40
|
-
remap
|
|
38
|
+
info="Observations file",
|
|
39
|
+
attr=dict(
|
|
40
|
+
kind=dict(
|
|
41
|
+
values=["observations", "obs"],
|
|
42
|
+
remap=dict(obs="observations"),
|
|
41
43
|
),
|
|
42
|
-
part
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
nativefmt = dict(
|
|
46
|
-
alias = ('format',),
|
|
44
|
+
part=dict(info="The name of this subset of observations."),
|
|
45
|
+
nativefmt=dict(
|
|
46
|
+
alias=("format",),
|
|
47
47
|
),
|
|
48
|
-
stage
|
|
49
|
-
info
|
|
48
|
+
stage=dict(
|
|
49
|
+
info="The processing stage for this subset of observations."
|
|
50
50
|
),
|
|
51
|
-
)
|
|
51
|
+
),
|
|
52
52
|
)
|
|
53
53
|
|
|
54
54
|
@property
|
|
55
55
|
def realkind(self):
|
|
56
|
-
return
|
|
56
|
+
return "observations"
|
|
57
57
|
|
|
58
58
|
|
|
59
59
|
class ObsProcessed(Observations):
|
|
60
60
|
"""Pre-Processed or Processed observations."""
|
|
61
61
|
|
|
62
62
|
_footprint = dict(
|
|
63
|
-
info
|
|
64
|
-
attr
|
|
65
|
-
nativefmt
|
|
66
|
-
values
|
|
63
|
+
info="Pre-Processed observations.",
|
|
64
|
+
attr=dict(
|
|
65
|
+
nativefmt=dict(
|
|
66
|
+
values=["ascii", "netcdf", "hdf5"],
|
|
67
67
|
),
|
|
68
|
-
stage
|
|
69
|
-
values
|
|
68
|
+
stage=dict(
|
|
69
|
+
values=[
|
|
70
|
+
"preprocessing",
|
|
71
|
+
],
|
|
70
72
|
),
|
|
71
|
-
)
|
|
73
|
+
),
|
|
72
74
|
)
|
|
73
75
|
|
|
74
76
|
|
|
75
|
-
@stddeco.namebuilding_insert(
|
|
77
|
+
@stddeco.namebuilding_insert("layout", lambda s: s.layout)
|
|
76
78
|
class ObsODB(Observations):
|
|
77
79
|
"""Observations in ODB format associated to a given stage."""
|
|
78
80
|
|
|
79
81
|
_footprint = dict(
|
|
80
|
-
info
|
|
81
|
-
attr
|
|
82
|
-
nativefmt
|
|
83
|
-
values
|
|
84
|
-
remap
|
|
85
|
-
'odb/split': 'odb',
|
|
86
|
-
'odb/compressed': 'odb'
|
|
87
|
-
},
|
|
82
|
+
info="Packed observations (ODB, CCMA, etc.)",
|
|
83
|
+
attr=dict(
|
|
84
|
+
nativefmt=dict(
|
|
85
|
+
values=["odb", "odb/split", "odb/compressed"],
|
|
86
|
+
remap={"odb/split": "odb", "odb/compressed": "odb"},
|
|
88
87
|
),
|
|
89
|
-
layout
|
|
90
|
-
info
|
|
91
|
-
optional
|
|
92
|
-
default
|
|
93
|
-
values
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
88
|
+
layout=dict(
|
|
89
|
+
info="The layout of the ODB database.",
|
|
90
|
+
optional=True,
|
|
91
|
+
default="ecma",
|
|
92
|
+
values=[
|
|
93
|
+
"ccma",
|
|
94
|
+
"ecma",
|
|
95
|
+
"ecmascr",
|
|
96
|
+
"CCMA",
|
|
97
|
+
"ECMA",
|
|
98
|
+
"ECMASCR",
|
|
99
|
+
"rstbias",
|
|
100
|
+
"countryrstrhbias",
|
|
101
|
+
"sondetyperstrhbias",
|
|
102
|
+
"RSTBIAS",
|
|
103
|
+
"COUNTRYRSTRHBIAS",
|
|
104
|
+
"SONDETYPERSTRHBIAS",
|
|
98
105
|
],
|
|
99
|
-
remap
|
|
100
|
-
CCMA
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
106
|
+
remap=dict(
|
|
107
|
+
CCMA="ccma",
|
|
108
|
+
ECMA="ecma",
|
|
109
|
+
ECMASCR="ecmascr",
|
|
110
|
+
RSTBIAS="rstbias",
|
|
111
|
+
COUNTRYRSTRHBIAS="countryrstrhbias",
|
|
112
|
+
SONDETYPERSTRHBIAS="sondetyperstrhbias",
|
|
113
|
+
),
|
|
105
114
|
),
|
|
106
|
-
stage
|
|
107
|
-
values
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
115
|
+
stage=dict(
|
|
116
|
+
values=[
|
|
117
|
+
"void",
|
|
118
|
+
"avg",
|
|
119
|
+
"average",
|
|
120
|
+
"screen",
|
|
121
|
+
"screening",
|
|
122
|
+
"split",
|
|
123
|
+
"build",
|
|
124
|
+
"traj",
|
|
125
|
+
"min",
|
|
126
|
+
"minim",
|
|
127
|
+
"complete",
|
|
128
|
+
"matchup",
|
|
129
|
+
"canari",
|
|
130
|
+
"cans",
|
|
111
131
|
],
|
|
112
|
-
remap
|
|
113
|
-
avg
|
|
114
|
-
min
|
|
115
|
-
cans
|
|
116
|
-
split
|
|
117
|
-
screen
|
|
132
|
+
remap=dict(
|
|
133
|
+
avg="average",
|
|
134
|
+
min="minim",
|
|
135
|
+
cans="canari",
|
|
136
|
+
split="build",
|
|
137
|
+
screen="screening",
|
|
118
138
|
),
|
|
119
139
|
),
|
|
120
|
-
)
|
|
140
|
+
),
|
|
121
141
|
)
|
|
122
142
|
|
|
123
143
|
def olive_basename(self):
|
|
124
144
|
"""OLIVE specific naming convention."""
|
|
125
|
-
stage_map = dict(
|
|
145
|
+
stage_map = dict(
|
|
146
|
+
screening="screen", build="split", minim="min", canari="cans"
|
|
147
|
+
)
|
|
126
148
|
mystage = stage_map.get(self.stage, self.stage)
|
|
127
|
-
return
|
|
149
|
+
return "_".join((self.layout, mystage, self.part)) + ".tar"
|
|
128
150
|
|
|
129
151
|
@property
|
|
130
152
|
def _archive_mapping(self):
|
|
131
|
-
re_fullmix = re.compile(r
|
|
132
|
-
ecma_map = dict(
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
153
|
+
re_fullmix = re.compile(r"^(?:altitude|mix|full)$")
|
|
154
|
+
ecma_map = dict(
|
|
155
|
+
void="ecmascr.tar",
|
|
156
|
+
screening="odb_screen.tar",
|
|
157
|
+
matchup="odb_cpl.tar",
|
|
158
|
+
complete="odb_cpl.tar",
|
|
159
|
+
)
|
|
160
|
+
ecma_prefix = {
|
|
161
|
+
("matchup", "arpege"): "BASE/",
|
|
162
|
+
("complete", "arpege"): "BASE/",
|
|
163
|
+
("matchup", "arome"): "BASE/",
|
|
164
|
+
("complete", "arome"): "BASE/",
|
|
165
|
+
("screening", "arome"): "./",
|
|
166
|
+
}
|
|
167
|
+
if self.stage in ecma_map and self.layout == "ecma":
|
|
141
168
|
if re_fullmix.match(self.part):
|
|
142
|
-
return (ecma_map[self.stage],
|
|
143
|
-
elif self.part ==
|
|
144
|
-
return (
|
|
145
|
-
|
|
146
|
-
|
|
169
|
+
return (ecma_map[self.stage], "extract=all&format=unknown")
|
|
170
|
+
elif self.part == "virtual":
|
|
171
|
+
return (
|
|
172
|
+
ecma_map[self.stage],
|
|
173
|
+
"extract={:s}ECMA&format=unknown".format(
|
|
174
|
+
ecma_prefix.get((self.stage, self.model), "")
|
|
175
|
+
),
|
|
176
|
+
)
|
|
147
177
|
else:
|
|
148
|
-
return (
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
elif
|
|
156
|
-
return (
|
|
157
|
-
elif re_fullmix.match(self.part) and self.stage ==
|
|
158
|
-
return (
|
|
159
|
-
elif
|
|
160
|
-
|
|
178
|
+
return (
|
|
179
|
+
ecma_map[self.stage],
|
|
180
|
+
"extract={:s}ECMA.{:s}&format=unknown".format(
|
|
181
|
+
ecma_prefix.get((self.stage, self.model), ""),
|
|
182
|
+
self.part,
|
|
183
|
+
),
|
|
184
|
+
)
|
|
185
|
+
elif self.stage == "screening" and self.layout == "ccma":
|
|
186
|
+
return ("odb_ccma_screen.tar", "")
|
|
187
|
+
elif re_fullmix.match(self.part) and self.stage == "traj":
|
|
188
|
+
return ("odb_traj.tar", "")
|
|
189
|
+
elif (
|
|
190
|
+
re_fullmix.match(self.part)
|
|
191
|
+
and self.stage == "minim"
|
|
192
|
+
and self.model == "aladin"
|
|
193
|
+
):
|
|
194
|
+
return ("odb_cpl.tar", "")
|
|
195
|
+
elif re_fullmix.match(self.part) and self.stage == "minim":
|
|
196
|
+
return ("odb_min.tar", "")
|
|
197
|
+
elif self.part in ("ground", "surf") and self.stage in (
|
|
198
|
+
"canari",
|
|
199
|
+
"surfan",
|
|
200
|
+
):
|
|
201
|
+
return ("odb_canari.tar", "")
|
|
161
202
|
else:
|
|
162
203
|
logger.error(
|
|
163
|
-
|
|
164
|
-
self.nativefmt,
|
|
204
|
+
"No archive basename defined for such observations (format=%s, part=%s, stage=%s)",
|
|
205
|
+
self.nativefmt,
|
|
206
|
+
self.part,
|
|
207
|
+
self.stage,
|
|
165
208
|
)
|
|
166
209
|
return (None, None)
|
|
167
210
|
|
|
@@ -180,88 +223,102 @@ class ObsRaw(Observations):
|
|
|
180
223
|
"""
|
|
181
224
|
|
|
182
225
|
_footprint = dict(
|
|
183
|
-
info
|
|
184
|
-
attr
|
|
185
|
-
nativefmt
|
|
186
|
-
values
|
|
187
|
-
remap
|
|
188
|
-
OBSOUL
|
|
189
|
-
GRIB
|
|
190
|
-
BUFR
|
|
191
|
-
ASCII
|
|
192
|
-
NETCDF
|
|
193
|
-
HDF5
|
|
194
|
-
)
|
|
195
|
-
),
|
|
196
|
-
stage = dict(
|
|
197
|
-
values = ['void', 'extract', 'raw', 'std']
|
|
226
|
+
info="Raw observations set",
|
|
227
|
+
attr=dict(
|
|
228
|
+
nativefmt=dict(
|
|
229
|
+
values=["obsoul", "grib", "bufr", "ascii", "netcdf", "hdf5"],
|
|
230
|
+
remap=dict(
|
|
231
|
+
OBSOUL="obsoul",
|
|
232
|
+
GRIB="grib",
|
|
233
|
+
BUFR="bufr",
|
|
234
|
+
ASCII="ascii",
|
|
235
|
+
NETCDF="netcdf",
|
|
236
|
+
HDF5="hdf5",
|
|
237
|
+
),
|
|
198
238
|
),
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
239
|
+
stage=dict(values=["void", "extract", "raw", "std"]),
|
|
240
|
+
olivefmt=dict(
|
|
241
|
+
info="The mapping between Vortex and Olive formats names.",
|
|
242
|
+
type=footprints.FPDict,
|
|
243
|
+
optional=True,
|
|
244
|
+
default=footprints.FPDict(
|
|
245
|
+
ascii="ascii",
|
|
246
|
+
obsoul="obsoul",
|
|
247
|
+
grib="obsgrib",
|
|
248
|
+
bufr="obsbufr",
|
|
249
|
+
netcdf="netcdf",
|
|
250
|
+
hdf5="hdf5",
|
|
210
251
|
),
|
|
211
|
-
doc_visibility
|
|
212
|
-
)
|
|
213
|
-
)
|
|
252
|
+
doc_visibility=footprints.doc.visibility.GURU,
|
|
253
|
+
),
|
|
254
|
+
),
|
|
214
255
|
)
|
|
215
256
|
|
|
216
257
|
def olive_basename(self):
|
|
217
258
|
"""OLIVE specific naming convention."""
|
|
218
|
-
return
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
259
|
+
return "_".join(
|
|
260
|
+
(
|
|
261
|
+
self.olivefmt.get(self.nativefmt, "obsfoo"),
|
|
262
|
+
self.stage,
|
|
263
|
+
self.part,
|
|
264
|
+
)
|
|
265
|
+
)
|
|
223
266
|
|
|
224
267
|
def archive_basename(self):
|
|
225
268
|
"""OP ARCHIVE specific naming convention."""
|
|
226
|
-
if (
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
269
|
+
if (
|
|
270
|
+
re.match(r"^(?:bufr|obsoul|grib|netcdf|hdf5)$", self.nativefmt)
|
|
271
|
+
and self.part != "full"
|
|
272
|
+
and self.stage == "void"
|
|
273
|
+
):
|
|
274
|
+
return ".".join((self.nativefmt, self.part))
|
|
275
|
+
elif (
|
|
276
|
+
re.match(r"^obsoul$", self.nativefmt)
|
|
277
|
+
and self.part == "full"
|
|
278
|
+
and self.stage == "void"
|
|
279
|
+
):
|
|
280
|
+
return "obsoul"
|
|
231
281
|
else:
|
|
232
282
|
logger.error(
|
|
233
|
-
|
|
234
|
-
self.nativefmt,
|
|
283
|
+
"No archive basename defined for such observations (format=%s, part=%s, stage=%s)",
|
|
284
|
+
self.nativefmt,
|
|
285
|
+
self.part,
|
|
286
|
+
self.stage,
|
|
235
287
|
)
|
|
236
288
|
|
|
237
289
|
|
|
238
|
-
@stddeco.namebuilding_insert(
|
|
239
|
-
@stddeco.namebuilding_insert(
|
|
290
|
+
@stddeco.namebuilding_insert("radical", lambda s: s.kind)
|
|
291
|
+
@stddeco.namebuilding_insert(
|
|
292
|
+
"src",
|
|
293
|
+
lambda s: [
|
|
294
|
+
s.part,
|
|
295
|
+
],
|
|
296
|
+
)
|
|
240
297
|
class ObsFlags(FlowResource):
|
|
241
298
|
"""Class for observations flags."""
|
|
242
299
|
|
|
243
300
|
_footprint = dict(
|
|
244
|
-
info
|
|
245
|
-
attr
|
|
246
|
-
kind
|
|
247
|
-
values
|
|
301
|
+
info="Observations flags",
|
|
302
|
+
attr=dict(
|
|
303
|
+
kind=dict(
|
|
304
|
+
values=["obsflag"],
|
|
248
305
|
),
|
|
249
306
|
nativefmt=dict(
|
|
250
|
-
values=[
|
|
251
|
-
default=
|
|
252
|
-
remap=dict(ascii=
|
|
307
|
+
values=["ascii", "txt"],
|
|
308
|
+
default="txt",
|
|
309
|
+
remap=dict(ascii="txt"),
|
|
253
310
|
),
|
|
254
|
-
part
|
|
311
|
+
part=dict(),
|
|
255
312
|
),
|
|
256
313
|
)
|
|
257
314
|
|
|
258
315
|
@property
|
|
259
316
|
def realkind(self):
|
|
260
|
-
return
|
|
317
|
+
return "obsflags"
|
|
261
318
|
|
|
262
319
|
def olive_basename(self):
|
|
263
320
|
"""OLIVE specific naming convention."""
|
|
264
|
-
return
|
|
321
|
+
return "BDM_CQ"
|
|
265
322
|
|
|
266
323
|
|
|
267
324
|
@nicedeco
|
|
@@ -278,7 +335,6 @@ def needs_slurp(mtd):
|
|
|
278
335
|
|
|
279
336
|
|
|
280
337
|
class VarBCContent(AlmostListContent):
|
|
281
|
-
|
|
282
338
|
# The VarBC file is too big: revert to the good old diff
|
|
283
339
|
_diffable = False
|
|
284
340
|
|
|
@@ -305,6 +361,7 @@ class VarBCContent(AlmostListContent):
|
|
|
305
361
|
if self._parsed_data is None:
|
|
306
362
|
# May fail if Numpy is not installed...
|
|
307
363
|
from bronx.datagrip.varbc import VarbcFile
|
|
364
|
+
|
|
308
365
|
self._parsed_data = VarbcFile(self.data)
|
|
309
366
|
return self._parsed_data
|
|
310
367
|
|
|
@@ -319,68 +376,86 @@ class VarBCContent(AlmostListContent):
|
|
|
319
376
|
self._do_delayed_slurp = container
|
|
320
377
|
with container.preferred_decoding(byte=False):
|
|
321
378
|
container.rewind()
|
|
322
|
-
self._metadata = VarbcHeadersFile(
|
|
379
|
+
self._metadata = VarbcHeadersFile(
|
|
380
|
+
[container.readline() for _ in range(3)]
|
|
381
|
+
)
|
|
323
382
|
|
|
324
383
|
|
|
325
|
-
@stddeco.namebuilding_append(
|
|
384
|
+
@stddeco.namebuilding_append(
|
|
385
|
+
"src",
|
|
386
|
+
lambda s: [
|
|
387
|
+
s.stage,
|
|
388
|
+
],
|
|
389
|
+
)
|
|
326
390
|
class VarBC(FlowResource):
|
|
327
391
|
"""
|
|
328
392
|
VarBC file resource. Contains all the coefficients for the VarBC bias correction scheme.
|
|
329
393
|
"""
|
|
330
394
|
|
|
331
395
|
_footprint = dict(
|
|
332
|
-
info
|
|
333
|
-
attr
|
|
334
|
-
kind
|
|
335
|
-
|
|
396
|
+
info="Varbc file (coefficients for the bias correction of observations).",
|
|
397
|
+
attr=dict(
|
|
398
|
+
kind=dict(values=["varbc"]),
|
|
399
|
+
clscontents=dict(
|
|
400
|
+
default=VarBCContent,
|
|
336
401
|
),
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
values = ['ascii', 'txt'],
|
|
342
|
-
default = 'txt',
|
|
343
|
-
remap = dict(ascii = 'txt'),
|
|
402
|
+
nativefmt=dict(
|
|
403
|
+
values=["ascii", "txt"],
|
|
404
|
+
default="txt",
|
|
405
|
+
remap=dict(ascii="txt"),
|
|
344
406
|
),
|
|
345
|
-
stage
|
|
346
|
-
optional
|
|
347
|
-
values
|
|
348
|
-
|
|
349
|
-
|
|
407
|
+
stage=dict(
|
|
408
|
+
optional=True,
|
|
409
|
+
values=[
|
|
410
|
+
"void",
|
|
411
|
+
"merge",
|
|
412
|
+
"screen",
|
|
413
|
+
"screening",
|
|
414
|
+
"minim",
|
|
415
|
+
"traj",
|
|
416
|
+
],
|
|
417
|
+
remap=dict(screen="screening"),
|
|
418
|
+
default="void",
|
|
350
419
|
),
|
|
351
|
-
mixmodel
|
|
352
|
-
optional
|
|
353
|
-
default
|
|
354
|
-
values
|
|
420
|
+
mixmodel=dict(
|
|
421
|
+
optional=True,
|
|
422
|
+
default=None,
|
|
423
|
+
values=stdattrs.models,
|
|
355
424
|
),
|
|
356
|
-
)
|
|
425
|
+
),
|
|
357
426
|
)
|
|
358
427
|
|
|
359
428
|
@property
|
|
360
429
|
def realkind(self):
|
|
361
|
-
return
|
|
430
|
+
return "varbc"
|
|
362
431
|
|
|
363
432
|
def olive_basename(self):
|
|
364
433
|
"""OLIVE specific naming convention."""
|
|
365
|
-
olivestage_map = {
|
|
366
|
-
|
|
434
|
+
olivestage_map = {
|
|
435
|
+
"screening": "screen",
|
|
436
|
+
}
|
|
437
|
+
return (
|
|
438
|
+
self.realkind.upper()
|
|
439
|
+
+ "."
|
|
440
|
+
+ olivestage_map.get(self.stage, self.stage)
|
|
441
|
+
)
|
|
367
442
|
|
|
368
443
|
def archive_basename(self):
|
|
369
444
|
"""OP ARCHIVE specific naming convention."""
|
|
370
|
-
if self.stage in (
|
|
371
|
-
bname =
|
|
445
|
+
if self.stage in ("void", "traj"):
|
|
446
|
+
bname = "VARBC.cycle"
|
|
372
447
|
if self.mixmodel is not None:
|
|
373
|
-
bname +=
|
|
374
|
-
if self.mixmodel.startswith(
|
|
448
|
+
bname += "_"
|
|
449
|
+
if self.mixmodel.startswith("alad"):
|
|
375
450
|
bname = bname + self.mixmodel[:4]
|
|
376
451
|
else:
|
|
377
452
|
bname = bname + self.mixmodel[:3]
|
|
378
453
|
else:
|
|
379
|
-
bname =
|
|
454
|
+
bname = "VARBC." + self.stage
|
|
380
455
|
return bname
|
|
381
456
|
|
|
382
457
|
|
|
383
|
-
@stddeco.namebuilding_insert(
|
|
458
|
+
@stddeco.namebuilding_insert("src", lambda s: s.scope)
|
|
384
459
|
class BlackList(FlowResource):
|
|
385
460
|
"""
|
|
386
461
|
TODO.
|
|
@@ -389,66 +464,73 @@ class BlackList(FlowResource):
|
|
|
389
464
|
_footprint = [
|
|
390
465
|
gvar,
|
|
391
466
|
dict(
|
|
392
|
-
info
|
|
393
|
-
attr
|
|
394
|
-
kind
|
|
395
|
-
values
|
|
396
|
-
),
|
|
397
|
-
gvar = dict(
|
|
398
|
-
default = 'blacklist_[scope]',
|
|
399
|
-
values = ['BLACKLIST_LOC', 'BLACKLIST_DIAP', 'BLACKLIST_LOCAL', 'BLACKLIST_GLOBAL'],
|
|
400
|
-
remap = dict(
|
|
401
|
-
BLACKLIST_LOCAL = 'BLACKLIST_LOC',
|
|
402
|
-
BLACKLIST_GLOBAL = 'BLACKLIST_DIAP',
|
|
403
|
-
blacklist_local = 'BLACKLIST_LOC',
|
|
404
|
-
blacklist_global = 'BLACKLIST_DIAP',
|
|
405
|
-
)
|
|
467
|
+
info="Blacklist file for observations",
|
|
468
|
+
attr=dict(
|
|
469
|
+
kind=dict(
|
|
470
|
+
values=["blacklist"],
|
|
406
471
|
),
|
|
407
|
-
|
|
408
|
-
default
|
|
472
|
+
gvar=dict(
|
|
473
|
+
default="blacklist_[scope]",
|
|
474
|
+
values=[
|
|
475
|
+
"BLACKLIST_LOC",
|
|
476
|
+
"BLACKLIST_DIAP",
|
|
477
|
+
"BLACKLIST_LOCAL",
|
|
478
|
+
"BLACKLIST_GLOBAL",
|
|
479
|
+
],
|
|
480
|
+
remap=dict(
|
|
481
|
+
BLACKLIST_LOCAL="BLACKLIST_LOC",
|
|
482
|
+
BLACKLIST_GLOBAL="BLACKLIST_DIAP",
|
|
483
|
+
blacklist_local="BLACKLIST_LOC",
|
|
484
|
+
blacklist_global="BLACKLIST_DIAP",
|
|
485
|
+
),
|
|
409
486
|
),
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
default = 'txt'
|
|
487
|
+
clscontents=dict(
|
|
488
|
+
default=TextContent,
|
|
413
489
|
),
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
loc
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
490
|
+
nativefmt=dict(values=["txt"], default="txt"),
|
|
491
|
+
scope=dict(
|
|
492
|
+
values=[
|
|
493
|
+
"loc",
|
|
494
|
+
"local",
|
|
495
|
+
"site",
|
|
496
|
+
"global",
|
|
497
|
+
"diap",
|
|
498
|
+
"diapason",
|
|
499
|
+
],
|
|
500
|
+
remap=dict(
|
|
501
|
+
loc="local",
|
|
502
|
+
site="local",
|
|
503
|
+
diap="global",
|
|
504
|
+
diapason="global",
|
|
505
|
+
),
|
|
422
506
|
),
|
|
423
|
-
)
|
|
424
|
-
)
|
|
507
|
+
),
|
|
508
|
+
),
|
|
425
509
|
]
|
|
426
510
|
|
|
427
511
|
@property
|
|
428
512
|
def realkind(self):
|
|
429
|
-
return
|
|
513
|
+
return "blacklist"
|
|
430
514
|
|
|
431
515
|
def iga_pathinfo(self):
|
|
432
516
|
"""Standard path information for IGA inline cache."""
|
|
433
|
-
return dict(
|
|
434
|
-
model=self.model
|
|
435
|
-
)
|
|
517
|
+
return dict(model=self.model)
|
|
436
518
|
|
|
437
519
|
def archive_map(self):
|
|
438
520
|
"""OP ARCHIVE specific naming convention."""
|
|
439
521
|
return {
|
|
440
|
-
|
|
441
|
-
|
|
522
|
+
"local": "LISTE_LOC",
|
|
523
|
+
"global": "LISTE_NOIRE_DIAP",
|
|
442
524
|
}
|
|
443
525
|
|
|
444
526
|
def archive_basename(self):
|
|
445
527
|
"""OP ARCHIVE local basename."""
|
|
446
528
|
mapd = self.archive_map()
|
|
447
|
-
return mapd.get(self.scope,
|
|
529
|
+
return mapd.get(self.scope, "LISTE_NOIRE_X")
|
|
448
530
|
|
|
449
531
|
|
|
450
532
|
#: A namedtuple of the internal fields of an ObsRef file
|
|
451
|
-
ObsRefItem = namedtuple(
|
|
533
|
+
ObsRefItem = namedtuple("ObsRefItem", ("data", "fmt", "instr", "date", "time"))
|
|
452
534
|
|
|
453
535
|
|
|
454
536
|
class ObsRefContent(TextContent):
|
|
@@ -460,51 +542,55 @@ class ObsRefContent(TextContent):
|
|
|
460
542
|
|
|
461
543
|
def slurp(self, container):
|
|
462
544
|
with container.preferred_decoding(byte=False):
|
|
463
|
-
self._data.extend(
|
|
545
|
+
self._data.extend(
|
|
546
|
+
[
|
|
547
|
+
ObsRefItem(*x.split()[:5])
|
|
548
|
+
for x in container
|
|
549
|
+
if not x.startswith("#")
|
|
550
|
+
]
|
|
551
|
+
)
|
|
464
552
|
self._size = container.totalsize
|
|
465
553
|
|
|
466
554
|
@classmethod
|
|
467
555
|
def formatted_data(self, item):
|
|
468
556
|
"""Return a formatted string."""
|
|
469
|
-
return
|
|
557
|
+
return "{:8s} {:8s} {:16s} {:s} {!s}".format(
|
|
470
558
|
item.data, item.fmt, item.instr, str(item.date), item.time
|
|
471
559
|
)
|
|
472
560
|
|
|
473
561
|
|
|
474
|
-
@stddeco.namebuilding_append(
|
|
562
|
+
@stddeco.namebuilding_append(
|
|
563
|
+
"src",
|
|
564
|
+
lambda s: [
|
|
565
|
+
s.part,
|
|
566
|
+
],
|
|
567
|
+
)
|
|
475
568
|
class Refdata(FlowResource):
|
|
476
569
|
"""
|
|
477
570
|
TODO.
|
|
478
571
|
"""
|
|
479
572
|
|
|
480
573
|
_footprint = dict(
|
|
481
|
-
info
|
|
482
|
-
attr
|
|
483
|
-
kind
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
clscontents = dict(
|
|
487
|
-
default = ObsRefContent,
|
|
574
|
+
info="Refdata file",
|
|
575
|
+
attr=dict(
|
|
576
|
+
kind=dict(values=["refdata"]),
|
|
577
|
+
clscontents=dict(
|
|
578
|
+
default=ObsRefContent,
|
|
488
579
|
),
|
|
489
|
-
nativefmt
|
|
490
|
-
values
|
|
491
|
-
default = 'txt',
|
|
492
|
-
remap = dict(ascii = 'txt')
|
|
493
|
-
),
|
|
494
|
-
part = dict(
|
|
495
|
-
optional = True,
|
|
496
|
-
default = 'all'
|
|
580
|
+
nativefmt=dict(
|
|
581
|
+
values=["ascii", "txt"], default="txt", remap=dict(ascii="txt")
|
|
497
582
|
),
|
|
498
|
-
|
|
583
|
+
part=dict(optional=True, default="all"),
|
|
584
|
+
),
|
|
499
585
|
)
|
|
500
586
|
|
|
501
587
|
@property
|
|
502
588
|
def realkind(self):
|
|
503
|
-
return
|
|
589
|
+
return "refdata"
|
|
504
590
|
|
|
505
591
|
def olive_basename(self):
|
|
506
592
|
"""OLIVE specific naming convention."""
|
|
507
|
-
return self.realkind +
|
|
593
|
+
return self.realkind + "." + self.part
|
|
508
594
|
|
|
509
595
|
def archive_basename(self):
|
|
510
596
|
"""OP ARCHIVE specific naming convention."""
|
|
@@ -512,7 +598,7 @@ class Refdata(FlowResource):
|
|
|
512
598
|
|
|
513
599
|
|
|
514
600
|
#: A namedtuple of the internal fields of an ObsMap file
|
|
515
|
-
ObsMapItem = namedtuple(
|
|
601
|
+
ObsMapItem = namedtuple("ObsMapItem", ("odb", "data", "fmt", "instr"))
|
|
516
602
|
|
|
517
603
|
|
|
518
604
|
class ObsMapContent(TextContent):
|
|
@@ -545,8 +631,8 @@ class ObsMapContent(TextContent):
|
|
|
545
631
|
"""
|
|
546
632
|
|
|
547
633
|
def __init__(self, **kw):
|
|
548
|
-
kw.setdefault(
|
|
549
|
-
kw.setdefault(
|
|
634
|
+
kw.setdefault("discarded", set())
|
|
635
|
+
kw.setdefault("only", None)
|
|
550
636
|
super().__init__(**kw)
|
|
551
637
|
|
|
552
638
|
@property
|
|
@@ -566,30 +652,41 @@ class ObsMapContent(TextContent):
|
|
|
566
652
|
def slurp(self, container):
|
|
567
653
|
"""Get data from the ``container``."""
|
|
568
654
|
if self.only is not None:
|
|
569
|
-
ofilters = [
|
|
570
|
-
|
|
655
|
+
ofilters = [
|
|
656
|
+
re.compile(d if ":" in d else d + ":") for d in self.only
|
|
657
|
+
]
|
|
571
658
|
else:
|
|
572
659
|
ofilters = None
|
|
573
|
-
dfilters = [
|
|
660
|
+
dfilters = [
|
|
661
|
+
re.compile(d if ":" in d else d + ":") for d in self.discarded
|
|
662
|
+
]
|
|
574
663
|
|
|
575
664
|
def item_filter(omline):
|
|
576
|
-
om =
|
|
577
|
-
return (
|
|
578
|
-
|
|
579
|
-
|
|
665
|
+
om = ":".join([omline.odb, omline.data])
|
|
666
|
+
return (
|
|
667
|
+
ofilters is None or any([f.match(om) for f in ofilters])
|
|
668
|
+
) and not any([f.match(om) for f in dfilters])
|
|
580
669
|
|
|
581
670
|
with container.preferred_decoding(byte=False):
|
|
582
671
|
container.rewind()
|
|
583
|
-
self.extend(
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
672
|
+
self.extend(
|
|
673
|
+
filter(
|
|
674
|
+
item_filter,
|
|
675
|
+
[
|
|
676
|
+
ObsMapItem(*x.split())
|
|
677
|
+
for x in [line.strip() for line in container]
|
|
678
|
+
if x and not x.startswith("#")
|
|
679
|
+
],
|
|
680
|
+
)
|
|
681
|
+
)
|
|
587
682
|
self._size = container.totalsize
|
|
588
683
|
|
|
589
684
|
@classmethod
|
|
590
685
|
def formatted_data(self, item):
|
|
591
686
|
"""Return a formatted string."""
|
|
592
|
-
return
|
|
687
|
+
return "{:12s} {:12s} {:12s} {:s}".format(
|
|
688
|
+
item.odb, item.data, item.fmt, item.instr
|
|
689
|
+
)
|
|
593
690
|
|
|
594
691
|
def odbset(self):
|
|
595
692
|
"""Return set of odb values."""
|
|
@@ -623,15 +720,15 @@ class ObsMapContent(TextContent):
|
|
|
623
720
|
|
|
624
721
|
These naming convention refer to the footprints resolve mechanism.
|
|
625
722
|
"""
|
|
626
|
-
part = g.get(
|
|
723
|
+
part = g.get("part", x.get("part", None))
|
|
627
724
|
if part is None:
|
|
628
725
|
return None
|
|
629
726
|
else:
|
|
630
727
|
return self.datafmt(part)
|
|
631
728
|
|
|
632
729
|
|
|
633
|
-
@stddeco.namebuilding_insert(
|
|
634
|
-
@stddeco.namebuilding_insert(
|
|
730
|
+
@stddeco.namebuilding_insert("style", lambda s: "obsmap")
|
|
731
|
+
@stddeco.namebuilding_insert("stage", lambda s: [s.scope, s.stage])
|
|
635
732
|
class ObsMap(FlowResource):
|
|
636
733
|
"""Observation mapping.
|
|
637
734
|
|
|
@@ -648,46 +745,43 @@ class ObsMap(FlowResource):
|
|
|
648
745
|
_footprint = [
|
|
649
746
|
gvar,
|
|
650
747
|
dict(
|
|
651
|
-
info
|
|
652
|
-
attr
|
|
653
|
-
kind
|
|
654
|
-
values
|
|
748
|
+
info="Bator mapping file",
|
|
749
|
+
attr=dict(
|
|
750
|
+
kind=dict(
|
|
751
|
+
values=["obsmap"],
|
|
655
752
|
),
|
|
656
|
-
clscontents
|
|
657
|
-
default
|
|
753
|
+
clscontents=dict(
|
|
754
|
+
default=ObsMapContent,
|
|
658
755
|
),
|
|
659
|
-
nativefmt
|
|
660
|
-
values
|
|
661
|
-
default
|
|
662
|
-
remap
|
|
756
|
+
nativefmt=dict(
|
|
757
|
+
values=["ascii", "txt"],
|
|
758
|
+
default="txt",
|
|
759
|
+
remap=dict(ascii="txt"),
|
|
663
760
|
),
|
|
664
|
-
stage
|
|
665
|
-
|
|
666
|
-
|
|
761
|
+
stage=dict(optional=True, default="void"),
|
|
762
|
+
scope=dict(
|
|
763
|
+
optional=True,
|
|
764
|
+
default="full",
|
|
765
|
+
remap=dict(surf="surface"),
|
|
667
766
|
),
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
767
|
+
discard=dict(
|
|
768
|
+
info="Discard some lines of the mapping (see the class documentation).",
|
|
769
|
+
type=footprints.FPSet,
|
|
770
|
+
optional=True,
|
|
771
|
+
default=footprints.FPSet(),
|
|
672
772
|
),
|
|
673
|
-
|
|
674
|
-
info
|
|
675
|
-
type
|
|
676
|
-
optional
|
|
677
|
-
default = footprints.FPSet(),
|
|
773
|
+
only=dict(
|
|
774
|
+
info="Only retain some lines of the mapping (see the class documentation).",
|
|
775
|
+
type=footprints.FPSet,
|
|
776
|
+
optional=True,
|
|
678
777
|
),
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
type = footprints.FPSet,
|
|
682
|
-
optional = True,
|
|
683
|
-
)
|
|
684
|
-
)
|
|
685
|
-
)
|
|
778
|
+
),
|
|
779
|
+
),
|
|
686
780
|
]
|
|
687
781
|
|
|
688
782
|
@property
|
|
689
783
|
def realkind(self):
|
|
690
|
-
return
|
|
784
|
+
return "obsmap"
|
|
691
785
|
|
|
692
786
|
def contents_args(self):
|
|
693
787
|
"""Returns default arguments value to class content constructor."""
|
|
@@ -695,54 +789,52 @@ class ObsMap(FlowResource):
|
|
|
695
789
|
|
|
696
790
|
def olive_basename(self):
|
|
697
791
|
"""OLIVE specific naming convention."""
|
|
698
|
-
return
|
|
792
|
+
return "OBSMAP_" + self.stage
|
|
699
793
|
|
|
700
794
|
def archive_basename(self):
|
|
701
795
|
"""OP ARCHIVE specific naming convention."""
|
|
702
|
-
if self.scope.startswith(
|
|
703
|
-
return
|
|
796
|
+
if self.scope.startswith("surf"):
|
|
797
|
+
return "BATOR_MAP_" + self.scope[:4].lower()
|
|
704
798
|
else:
|
|
705
|
-
return
|
|
799
|
+
return "BATOR_MAP"
|
|
706
800
|
|
|
707
801
|
def genv_basename(self):
|
|
708
802
|
"""Genv key naming convention."""
|
|
709
|
-
cutoff_map = {
|
|
803
|
+
cutoff_map = {"production": "prod"}
|
|
710
804
|
if self.gvar is None:
|
|
711
|
-
if self.scope ==
|
|
712
|
-
gkey =
|
|
805
|
+
if self.scope == "surface":
|
|
806
|
+
gkey = "bator_map_surf"
|
|
713
807
|
else:
|
|
714
|
-
gkey =
|
|
808
|
+
gkey = "bator_map_" + cutoff_map.get(self.cutoff, self.cutoff)
|
|
715
809
|
return GenvKey(gkey)
|
|
716
810
|
else:
|
|
717
811
|
return self.gvar
|
|
718
812
|
|
|
719
813
|
|
|
720
|
-
@stddeco.namebuilding_insert(
|
|
814
|
+
@stddeco.namebuilding_insert("src", lambda s: s.satbias)
|
|
721
815
|
class Bcor(FlowResource):
|
|
722
816
|
"""Bias correction parameters."""
|
|
723
817
|
|
|
724
818
|
_footprint = dict(
|
|
725
|
-
info
|
|
726
|
-
attr
|
|
727
|
-
kind
|
|
728
|
-
values
|
|
819
|
+
info="Bias correction parameters",
|
|
820
|
+
attr=dict(
|
|
821
|
+
kind=dict(
|
|
822
|
+
values=["bcor"],
|
|
729
823
|
),
|
|
730
|
-
nativefmt
|
|
731
|
-
values
|
|
732
|
-
default = 'txt',
|
|
733
|
-
remap = dict(ascii = 'txt')
|
|
824
|
+
nativefmt=dict(
|
|
825
|
+
values=["ascii", "txt"], default="txt", remap=dict(ascii="txt")
|
|
734
826
|
),
|
|
735
|
-
satbias
|
|
736
|
-
values
|
|
737
|
-
remap
|
|
827
|
+
satbias=dict(
|
|
828
|
+
values=["mtop", "metop", "noaa", "ssmi"],
|
|
829
|
+
remap=dict(metop="mtop"),
|
|
738
830
|
),
|
|
739
|
-
)
|
|
831
|
+
),
|
|
740
832
|
)
|
|
741
833
|
|
|
742
834
|
@property
|
|
743
835
|
def realkind(self):
|
|
744
|
-
return
|
|
836
|
+
return "bcor"
|
|
745
837
|
|
|
746
838
|
def archive_basename(self):
|
|
747
839
|
"""OP ARCHIVE specific naming convention."""
|
|
748
|
-
return
|
|
840
|
+
return "bcor_" + self.satbias + ".dat"
|