vortex-nwp 2.0.0b1__py3-none-any.whl → 2.0.0b2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. vortex/__init__.py +59 -45
  2. vortex/algo/__init__.py +3 -2
  3. vortex/algo/components.py +940 -614
  4. vortex/algo/mpitools.py +802 -497
  5. vortex/algo/serversynctools.py +34 -33
  6. vortex/config.py +19 -22
  7. vortex/data/__init__.py +9 -3
  8. vortex/data/abstractstores.py +593 -655
  9. vortex/data/containers.py +217 -162
  10. vortex/data/contents.py +65 -39
  11. vortex/data/executables.py +93 -102
  12. vortex/data/flow.py +40 -34
  13. vortex/data/geometries.py +228 -132
  14. vortex/data/handlers.py +428 -225
  15. vortex/data/outflow.py +15 -15
  16. vortex/data/providers.py +185 -163
  17. vortex/data/resources.py +48 -42
  18. vortex/data/stores.py +544 -413
  19. vortex/gloves.py +114 -87
  20. vortex/layout/__init__.py +1 -8
  21. vortex/layout/contexts.py +150 -84
  22. vortex/layout/dataflow.py +353 -202
  23. vortex/layout/monitor.py +264 -128
  24. vortex/nwp/__init__.py +5 -2
  25. vortex/nwp/algo/__init__.py +14 -5
  26. vortex/nwp/algo/assim.py +205 -151
  27. vortex/nwp/algo/clim.py +683 -517
  28. vortex/nwp/algo/coupling.py +447 -225
  29. vortex/nwp/algo/eda.py +437 -229
  30. vortex/nwp/algo/eps.py +403 -231
  31. vortex/nwp/algo/forecasts.py +420 -271
  32. vortex/nwp/algo/fpserver.py +683 -307
  33. vortex/nwp/algo/ifsnaming.py +205 -145
  34. vortex/nwp/algo/ifsroot.py +210 -122
  35. vortex/nwp/algo/monitoring.py +132 -76
  36. vortex/nwp/algo/mpitools.py +321 -191
  37. vortex/nwp/algo/odbtools.py +617 -353
  38. vortex/nwp/algo/oopsroot.py +449 -273
  39. vortex/nwp/algo/oopstests.py +90 -56
  40. vortex/nwp/algo/request.py +287 -206
  41. vortex/nwp/algo/stdpost.py +878 -522
  42. vortex/nwp/data/__init__.py +22 -4
  43. vortex/nwp/data/assim.py +125 -137
  44. vortex/nwp/data/boundaries.py +121 -68
  45. vortex/nwp/data/climfiles.py +193 -211
  46. vortex/nwp/data/configfiles.py +73 -69
  47. vortex/nwp/data/consts.py +426 -401
  48. vortex/nwp/data/ctpini.py +59 -43
  49. vortex/nwp/data/diagnostics.py +94 -66
  50. vortex/nwp/data/eda.py +50 -51
  51. vortex/nwp/data/eps.py +195 -146
  52. vortex/nwp/data/executables.py +440 -434
  53. vortex/nwp/data/fields.py +63 -48
  54. vortex/nwp/data/gridfiles.py +183 -111
  55. vortex/nwp/data/logs.py +250 -217
  56. vortex/nwp/data/modelstates.py +180 -151
  57. vortex/nwp/data/monitoring.py +72 -99
  58. vortex/nwp/data/namelists.py +254 -202
  59. vortex/nwp/data/obs.py +400 -308
  60. vortex/nwp/data/oopsexec.py +22 -20
  61. vortex/nwp/data/providers.py +90 -65
  62. vortex/nwp/data/query.py +71 -82
  63. vortex/nwp/data/stores.py +49 -36
  64. vortex/nwp/data/surfex.py +136 -137
  65. vortex/nwp/syntax/__init__.py +1 -1
  66. vortex/nwp/syntax/stdattrs.py +173 -111
  67. vortex/nwp/tools/__init__.py +2 -2
  68. vortex/nwp/tools/addons.py +22 -17
  69. vortex/nwp/tools/agt.py +24 -12
  70. vortex/nwp/tools/bdap.py +16 -5
  71. vortex/nwp/tools/bdcp.py +4 -1
  72. vortex/nwp/tools/bdm.py +3 -0
  73. vortex/nwp/tools/bdmp.py +14 -9
  74. vortex/nwp/tools/conftools.py +728 -378
  75. vortex/nwp/tools/drhook.py +12 -8
  76. vortex/nwp/tools/grib.py +65 -39
  77. vortex/nwp/tools/gribdiff.py +22 -17
  78. vortex/nwp/tools/ifstools.py +82 -42
  79. vortex/nwp/tools/igastuff.py +167 -143
  80. vortex/nwp/tools/mars.py +14 -2
  81. vortex/nwp/tools/odb.py +234 -125
  82. vortex/nwp/tools/partitioning.py +61 -37
  83. vortex/nwp/tools/satrad.py +27 -12
  84. vortex/nwp/util/async.py +83 -55
  85. vortex/nwp/util/beacon.py +10 -10
  86. vortex/nwp/util/diffpygram.py +174 -86
  87. vortex/nwp/util/ens.py +144 -63
  88. vortex/nwp/util/hooks.py +30 -19
  89. vortex/nwp/util/taskdeco.py +28 -24
  90. vortex/nwp/util/usepygram.py +278 -172
  91. vortex/nwp/util/usetnt.py +31 -17
  92. vortex/sessions.py +72 -39
  93. vortex/syntax/__init__.py +1 -1
  94. vortex/syntax/stdattrs.py +410 -171
  95. vortex/syntax/stddeco.py +31 -22
  96. vortex/toolbox.py +327 -192
  97. vortex/tools/__init__.py +11 -2
  98. vortex/tools/actions.py +125 -59
  99. vortex/tools/addons.py +111 -92
  100. vortex/tools/arm.py +42 -22
  101. vortex/tools/compression.py +72 -69
  102. vortex/tools/date.py +11 -4
  103. vortex/tools/delayedactions.py +242 -132
  104. vortex/tools/env.py +75 -47
  105. vortex/tools/folder.py +342 -171
  106. vortex/tools/grib.py +311 -149
  107. vortex/tools/lfi.py +423 -216
  108. vortex/tools/listings.py +109 -40
  109. vortex/tools/names.py +218 -156
  110. vortex/tools/net.py +632 -298
  111. vortex/tools/parallelism.py +93 -61
  112. vortex/tools/prestaging.py +55 -31
  113. vortex/tools/schedulers.py +172 -105
  114. vortex/tools/services.py +402 -333
  115. vortex/tools/storage.py +293 -358
  116. vortex/tools/surfex.py +24 -24
  117. vortex/tools/systems.py +1211 -631
  118. vortex/tools/targets.py +156 -100
  119. vortex/util/__init__.py +1 -1
  120. vortex/util/config.py +377 -327
  121. vortex/util/empty.py +2 -2
  122. vortex/util/helpers.py +56 -24
  123. vortex/util/introspection.py +18 -12
  124. vortex/util/iosponge.py +8 -4
  125. vortex/util/roles.py +4 -6
  126. vortex/util/storefunctions.py +39 -13
  127. vortex/util/structs.py +3 -3
  128. vortex/util/worker.py +29 -17
  129. vortex_nwp-2.0.0b2.dist-info/METADATA +66 -0
  130. vortex_nwp-2.0.0b2.dist-info/RECORD +142 -0
  131. {vortex_nwp-2.0.0b1.dist-info → vortex_nwp-2.0.0b2.dist-info}/WHEEL +1 -1
  132. vortex/layout/appconf.py +0 -109
  133. vortex/layout/jobs.py +0 -1276
  134. vortex/layout/nodes.py +0 -1424
  135. vortex/layout/subjobs.py +0 -464
  136. vortex_nwp-2.0.0b1.dist-info/METADATA +0 -50
  137. vortex_nwp-2.0.0b1.dist-info/RECORD +0 -146
  138. {vortex_nwp-2.0.0b1.dist-info → vortex_nwp-2.0.0b2.dist-info}/LICENSE +0 -0
  139. {vortex_nwp-2.0.0b1.dist-info → vortex_nwp-2.0.0b2.dist-info}/top_level.txt +0 -0
@@ -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 AlgoComponent, AlgoComponentDecoMixin, Expresso, BlindRun
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 BDAPrequest_actual_command, BDAPGetError, BDAPRequestConfigurationError
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 = 'Algo component to get BDAP files.',
33
- attr = dict(
34
- kind = dict(
35
- values = ['get_bdap'],
41
+ info="Algo component to get BDAP files.",
42
+ attr=dict(
43
+ kind=dict(
44
+ values=["get_bdap"],
36
45
  ),
37
- date = a_date,
38
- target_bdap = dict(
39
- default = 'OPER',
40
- optional = True,
41
- values = ['OPER', 'INTE'],
46
+ date=a_date,
47
+ target_bdap=dict(
48
+ default="OPER",
49
+ optional=True,
50
+ values=["OPER", "INTE"],
42
51
  ),
43
- terms = dict(
44
- info = "A forecast term or a list of terms (rangex will be used to expand the string)",
45
- alias = ('term', )
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 = dict(
48
- default = 'dap3',
49
- optional =True,
50
- values = ['dap3', 'dap3_dev'],
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 == 'INTE'
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='Query',
68
- kind='bdap_query',
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 = '_'.join([query_file, self.date.ymdhms, term.fmtraw])
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(command=self.command,
84
- date=self.date,
85
- term=term,
86
- query=query_file,
87
- int_extraenv=int_bdap)
88
- logger.info(' '.join(['BDAP extract command:', actual_command]))
89
- logger.info('The %s directive file contains:', query_file)
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([actual_command, ], shell=True, output=False, fatal=False)
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('Problem during the BDAP request of %s.', query_file)
96
- if self.system.path.isfile('DIAG_BDAP'):
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('Problem during the BDAP request.')
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 = 'Algo component to get BDMP files.',
114
- attr = dict(
115
- kind = dict(
116
- values = ['get_bdmp'],
136
+ info="Algo component to get BDMP files.",
137
+ attr=dict(
138
+ kind=dict(
139
+ values=["get_bdmp"],
117
140
  ),
118
- target_bdmp = dict(
119
- default = 'OPER',
120
- optional = True,
121
- values = ['OPER', 'INTE', 'ARCH'],
141
+ target_bdmp=dict(
142
+ default="OPER",
143
+ optional=True,
144
+ values=["OPER", "INTE", "ARCH"],
122
145
  ),
123
- command = dict(
124
- default = 'bdmp_lecture',
125
- optional =True,
126
- values = ['bdmp_lecture', 'bdmp_lecture_pg', 'bdmp_lecture_ora'],
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='Query',
141
- kind='bdmp_query',
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('The %s directive file contains:', query_file)
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 = '_'.join([query_file, 'extract'])
176
+ local_directory = "_".join([query_file, "extract"])
155
177
 
156
178
  # Determine the command to be launched
157
- actual_command = BDMPrequest_actual_command(command=self.command,
158
- query=query_file,
159
- target_bdmp=self.target_bdmp)
160
- logger.info(' '.join(['BDMP extract command:', actual_command]))
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([actual_command, ], shell=True, output=False, fatal=False)
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('Problem during the BDMP request of %s.', query_file)
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('Problem during the BDMP request.')
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 = 'Algo component to get BDCP files.',
183
- attr = dict(
184
- kind = dict(
185
- values = ['get_bdcp'],
215
+ info="Algo component to get BDCP files.",
216
+ attr=dict(
217
+ kind=dict(
218
+ values=["get_bdcp"],
186
219
  ),
187
- target_bdcp = dict(
188
- default = 'OPER',
189
- optional = True,
190
- values = ['OPER'],
220
+ target_bdcp=dict(
221
+ default="OPER",
222
+ optional=True,
223
+ values=["OPER"],
191
224
  ),
192
- command = dict(
193
- default = 'extraction_directives',
194
- optional =True,
195
- values = ['extraction_directives'],
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='Query',
210
- kind='bdcp_query',
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('The %s directive file contains:', query_file)
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 = '_'.join([query_file, 'extract'])
224
- output_file = 'extract.out'
225
- output_log = 'extract.out.diag'
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(command=self.command,
229
- query_file=query_file,
230
- output_file=output_file)
231
- logger.info(' '.join(['BDMP extract command:', actual_command]))
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([actual_command, ], shell=True, output=False, fatal=False)
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('Content of the log file:')
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('Problem during the BDCP request of %s.', query_file)
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('Problem during the BDCP request.')
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 = [footprints.Footprint(
257
- attr=dict(
258
- date=a_date,
259
- pwd_file=dict(
260
- default='/usr/local/sopra/neons_pwd',
261
- values=['/usr/local/sopra/neons_pwd'],
262
- optional=True,
263
- ),
264
- fatal=dict(
265
- type=bool,
266
- default=False,
267
- values=[True, False],
268
- optional=True,
269
- ),
270
- defaut_queryname=dict(
271
- default='vortexdefault_query_name',
272
- doc_visibility=footprints.doc.visibility.GURU,
273
- optional=True,
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('Setting environment variable %s = %s', varname, str(value))
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('PWD_FILE', self.pwd_file)
288
- self._verbose_env_export('DMT_DATE_PIVOT', self.date.ymdhms)
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['query'] = self.defaut_queryname
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('The %s directive file contains:', query_filename)
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(rh, opts)
373
+ super(self.mixin_execute_companion(), self).execute(
374
+ rh, opts
375
+ )
328
376
  except ExecutionError:
329
377
  rc_all = False
330
- logger.error('Problem during the BDM request of %s.', query_filename)
378
+ logger.error(
379
+ "Problem during the BDM request of %s.", query_filename
380
+ )
331
381
  if self.fatal:
332
- raise BDMGetError('Problem during the BDM request of {}.'.format(query_filename))
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('At least one of the BDM request failed. Please check the logs above.')
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 = [self._local_directory(input_query.rh.container.filename)
349
- for input_query in input_queries]
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('/'.join([directory, '*batormap*']))
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 = '_'.join(['OBSMAP', self.date.ymdhms])
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('Content of the global batormap:')
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 = 'OULOUTPUT'
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('/'.join([directory, listing_filename]))
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 = '.'.join([listing_filename, 'tmp'])
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 = 'Algo component to get BDM BUFR.',
401
- attr = dict(
402
- kind = dict(
403
- values = ['get_bdm_bufr'],
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 = dict(
406
- default = '/usr/local/sopra/neons_db_bdm',
407
- values = ['/usr/local/sopra/neons_db_bdm',
408
- '/usr/local/sopra/neons_db_bdm.archi',
409
- '/usr/local/sopra/neons_db_bdm.intgr'],
410
- optional = True,
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 = dict(
413
- values = ['RECHERCHE', 'OPERATIONNEL', 'OPER'],
414
- default = 'OPER',
415
- optional = True,
474
+ extra_env_opt=dict(
475
+ values=["RECHERCHE", "OPERATIONNEL", "OPER"],
476
+ default="OPER",
477
+ optional=True,
416
478
  ),
417
- shlib_path = dict(
418
- default = '/usr/local/lib',
419
- optional = True,
479
+ shlib_path=dict(
480
+ default="/usr/local/lib",
481
+ optional=True,
420
482
  ),
421
- interpreter = dict(
422
- default = 'awk',
423
- values = ['awk'],
424
- optional = True,
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 '_'.join(['BUFR', query_filename, self.date.ymdhms])
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='Query',
436
- kind='bdm_query',
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('EXTR_ENV', self.extra_env_opt)
448
- self._verbose_env_export('DB_FILE_BDM', self.db_file_bdm)
449
- self._verbose_env_export('SHLIB_PATH', ':'.join(['$SHLIB_PATH', self.shlib_path]))
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('No query file found for the BDM extraction. Stop.')
455
- raise BDMRequestConfigurationError('No query file found for the BDM extraction')
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 = "Algo component to get BDM files using Oulan.",
463
- attr = dict(
464
- kind = dict(
465
- values = ['get_bdm_oulan'],
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 = dict(
468
- default = '/usr/local/sopra/neons_db',
469
- values = ['/usr/local/sopra/neons_db'],
470
- optional = True,
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 = dict(
473
- default = 'NAMELIST',
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 '_'.join(['Oulan', query_filename, self.date.ymdhms])
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='NamelistOulan',
485
- kind='namutil',
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('DB_FILE', self.db_file)
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('No Oulan namelist found. Stop.')
500
- raise BDMError('No Oulan namelist found.')
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 = 'AlgoComponent to get a Mars resource',
508
- attr = dict(
509
- kind = dict(
510
- values = ['get_mars', ]
511
- ),
512
- date = a_date,
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
- command = dict(
520
- optional = True
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
- fatal = dict(
523
- type = bool,
524
- default = True,
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='Query',
539
- kind='mars_query',
602
+ role="Query",
603
+ kind="mars_query",
540
604
  )
541
605
  if len(input_queries) < 1:
542
- logger.exception('No query file found for the Mars extraction. Stop.')
543
- raise MarsGetError('No query file found for the Mars extraction')
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(sh=self.system, command=self.command)
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 = '_'.join([query_file_path, self.date.ymdhms])
567
- logger.info("Here is the content of the query file %s (after substitution):", query_file_path)
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(sh=self.system, query_file=query_file_path, fatal=self.fatal,
572
- command=actual_command)
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("Problem during the Mars request of %s", query_file_path)
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("Problem during the Mars request of %s", query_file_path)
656
+ logger.warning(
657
+ "Problem during the Mars request of %s",
658
+ query_file_path,
659
+ )
579
660
  rc_all = rc_all and rc