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.
Files changed (141) hide show
  1. vortex/__init__.py +75 -47
  2. vortex/algo/__init__.py +3 -2
  3. vortex/algo/components.py +944 -618
  4. vortex/algo/mpitools.py +802 -497
  5. vortex/algo/mpitools_templates/__init__.py +1 -0
  6. vortex/algo/serversynctools.py +34 -33
  7. vortex/config.py +19 -22
  8. vortex/data/__init__.py +9 -3
  9. vortex/data/abstractstores.py +593 -655
  10. vortex/data/containers.py +217 -162
  11. vortex/data/contents.py +65 -39
  12. vortex/data/executables.py +93 -102
  13. vortex/data/flow.py +40 -34
  14. vortex/data/geometries.py +228 -132
  15. vortex/data/handlers.py +436 -227
  16. vortex/data/outflow.py +15 -15
  17. vortex/data/providers.py +185 -163
  18. vortex/data/resources.py +48 -42
  19. vortex/data/stores.py +540 -417
  20. vortex/data/sync_templates/__init__.py +0 -0
  21. vortex/gloves.py +114 -87
  22. vortex/layout/__init__.py +1 -8
  23. vortex/layout/contexts.py +150 -84
  24. vortex/layout/dataflow.py +353 -202
  25. vortex/layout/monitor.py +264 -128
  26. vortex/nwp/__init__.py +5 -2
  27. vortex/nwp/algo/__init__.py +14 -5
  28. vortex/nwp/algo/assim.py +205 -151
  29. vortex/nwp/algo/clim.py +683 -517
  30. vortex/nwp/algo/coupling.py +447 -225
  31. vortex/nwp/algo/eda.py +437 -229
  32. vortex/nwp/algo/eps.py +403 -231
  33. vortex/nwp/algo/forecasts.py +416 -275
  34. vortex/nwp/algo/fpserver.py +683 -307
  35. vortex/nwp/algo/ifsnaming.py +205 -145
  36. vortex/nwp/algo/ifsroot.py +215 -122
  37. vortex/nwp/algo/monitoring.py +137 -76
  38. vortex/nwp/algo/mpitools.py +330 -190
  39. vortex/nwp/algo/odbtools.py +637 -353
  40. vortex/nwp/algo/oopsroot.py +454 -273
  41. vortex/nwp/algo/oopstests.py +90 -56
  42. vortex/nwp/algo/request.py +287 -206
  43. vortex/nwp/algo/stdpost.py +878 -522
  44. vortex/nwp/data/__init__.py +22 -4
  45. vortex/nwp/data/assim.py +125 -137
  46. vortex/nwp/data/boundaries.py +121 -68
  47. vortex/nwp/data/climfiles.py +193 -211
  48. vortex/nwp/data/configfiles.py +73 -69
  49. vortex/nwp/data/consts.py +426 -401
  50. vortex/nwp/data/ctpini.py +59 -43
  51. vortex/nwp/data/diagnostics.py +94 -66
  52. vortex/nwp/data/eda.py +50 -51
  53. vortex/nwp/data/eps.py +195 -146
  54. vortex/nwp/data/executables.py +440 -434
  55. vortex/nwp/data/fields.py +63 -48
  56. vortex/nwp/data/gridfiles.py +183 -111
  57. vortex/nwp/data/logs.py +250 -217
  58. vortex/nwp/data/modelstates.py +180 -151
  59. vortex/nwp/data/monitoring.py +72 -99
  60. vortex/nwp/data/namelists.py +254 -202
  61. vortex/nwp/data/obs.py +400 -308
  62. vortex/nwp/data/oopsexec.py +22 -20
  63. vortex/nwp/data/providers.py +90 -65
  64. vortex/nwp/data/query.py +71 -82
  65. vortex/nwp/data/stores.py +49 -36
  66. vortex/nwp/data/surfex.py +136 -137
  67. vortex/nwp/syntax/__init__.py +1 -1
  68. vortex/nwp/syntax/stdattrs.py +173 -111
  69. vortex/nwp/tools/__init__.py +2 -2
  70. vortex/nwp/tools/addons.py +22 -17
  71. vortex/nwp/tools/agt.py +24 -12
  72. vortex/nwp/tools/bdap.py +16 -5
  73. vortex/nwp/tools/bdcp.py +4 -1
  74. vortex/nwp/tools/bdm.py +3 -0
  75. vortex/nwp/tools/bdmp.py +14 -9
  76. vortex/nwp/tools/conftools.py +728 -378
  77. vortex/nwp/tools/drhook.py +12 -8
  78. vortex/nwp/tools/grib.py +65 -39
  79. vortex/nwp/tools/gribdiff.py +22 -17
  80. vortex/nwp/tools/ifstools.py +82 -42
  81. vortex/nwp/tools/igastuff.py +167 -143
  82. vortex/nwp/tools/mars.py +14 -2
  83. vortex/nwp/tools/odb.py +234 -125
  84. vortex/nwp/tools/partitioning.py +61 -37
  85. vortex/nwp/tools/satrad.py +27 -12
  86. vortex/nwp/util/async.py +83 -55
  87. vortex/nwp/util/beacon.py +10 -10
  88. vortex/nwp/util/diffpygram.py +174 -86
  89. vortex/nwp/util/ens.py +144 -63
  90. vortex/nwp/util/hooks.py +30 -19
  91. vortex/nwp/util/taskdeco.py +28 -24
  92. vortex/nwp/util/usepygram.py +278 -172
  93. vortex/nwp/util/usetnt.py +31 -17
  94. vortex/sessions.py +72 -39
  95. vortex/syntax/__init__.py +1 -1
  96. vortex/syntax/stdattrs.py +410 -171
  97. vortex/syntax/stddeco.py +31 -22
  98. vortex/toolbox.py +327 -192
  99. vortex/tools/__init__.py +11 -2
  100. vortex/tools/actions.py +110 -121
  101. vortex/tools/addons.py +111 -92
  102. vortex/tools/arm.py +42 -22
  103. vortex/tools/compression.py +72 -69
  104. vortex/tools/date.py +11 -4
  105. vortex/tools/delayedactions.py +242 -132
  106. vortex/tools/env.py +75 -47
  107. vortex/tools/folder.py +342 -171
  108. vortex/tools/grib.py +341 -162
  109. vortex/tools/lfi.py +423 -216
  110. vortex/tools/listings.py +109 -40
  111. vortex/tools/names.py +218 -156
  112. vortex/tools/net.py +655 -299
  113. vortex/tools/parallelism.py +93 -61
  114. vortex/tools/prestaging.py +55 -31
  115. vortex/tools/schedulers.py +172 -105
  116. vortex/tools/services.py +403 -334
  117. vortex/tools/storage.py +293 -358
  118. vortex/tools/surfex.py +24 -24
  119. vortex/tools/systems.py +1234 -643
  120. vortex/tools/targets.py +156 -100
  121. vortex/util/__init__.py +1 -1
  122. vortex/util/config.py +378 -327
  123. vortex/util/empty.py +2 -2
  124. vortex/util/helpers.py +56 -24
  125. vortex/util/introspection.py +18 -12
  126. vortex/util/iosponge.py +8 -4
  127. vortex/util/roles.py +4 -6
  128. vortex/util/storefunctions.py +39 -13
  129. vortex/util/structs.py +3 -3
  130. vortex/util/worker.py +29 -17
  131. vortex_nwp-2.1.0.dist-info/METADATA +67 -0
  132. vortex_nwp-2.1.0.dist-info/RECORD +144 -0
  133. {vortex_nwp-2.0.0b1.dist-info → vortex_nwp-2.1.0.dist-info}/WHEEL +1 -1
  134. vortex/layout/appconf.py +0 -109
  135. vortex/layout/jobs.py +0 -1276
  136. vortex/layout/nodes.py +0 -1424
  137. vortex/layout/subjobs.py +0 -464
  138. vortex_nwp-2.0.0b1.dist-info/METADATA +0 -50
  139. vortex_nwp-2.0.0b1.dist-info/RECORD +0 -146
  140. {vortex_nwp-2.0.0b1.dist-info → vortex_nwp-2.1.0.dist-info/licenses}/LICENSE +0 -0
  141. {vortex_nwp-2.0.0b1.dist-info → vortex_nwp-2.1.0.dist-info}/top_level.txt +0 -0
@@ -11,7 +11,7 @@ from vortex.syntax.stddeco import namebuilding_append
11
11
  __all__ = []
12
12
 
13
13
 
14
- @namebuilding_append('src', lambda self: self.run)
14
+ @namebuilding_append("src", lambda self: self.run)
15
15
  class OOPSBinary(NWPModel):
16
16
  """Yet an other OOPS Binary."""
17
17
 
@@ -21,30 +21,32 @@ class OOPSBinary(NWPModel):
21
21
  oops_run,
22
22
  executable_flavour_deco,
23
23
  dict(
24
- info = 'OOPS Binary: an OOPS binary, dedicated to a task (a run in OOPS namespace).',
25
- attr = dict(
26
- kind = dict(
27
- values = ['oopsbinary', ],
24
+ info="OOPS Binary: an OOPS binary, dedicated to a task (a run in OOPS namespace).",
25
+ attr=dict(
26
+ kind=dict(
27
+ values=[
28
+ "oopsbinary",
29
+ ],
28
30
  ),
29
- gvar = dict(
30
- default = 'master_[run]',
31
+ gvar=dict(
32
+ default="master_[run]",
31
33
  ),
32
- run = dict(
33
- outcast = known_oops_testcomponent_runs,
34
+ run=dict(
35
+ outcast=known_oops_testcomponent_runs,
34
36
  ),
35
- )
36
- )
37
+ ),
38
+ ),
37
39
  ]
38
40
 
39
41
  @property
40
42
  def realkind(self):
41
- return 'oopsbinary'
43
+ return "oopsbinary"
42
44
 
43
45
  def command_line(self, configfile):
44
46
  """
45
47
  Build command line for execution as a single string.
46
48
  """
47
- cmdline = '{}'.format(configfile)
49
+ cmdline = "{}".format(configfile)
48
50
  return cmdline
49
51
 
50
52
 
@@ -52,11 +54,11 @@ class OOPSTestComponent(OOPSBinary):
52
54
  """Binary for OOPS Tests of components."""
53
55
 
54
56
  _footprint = dict(
55
- info = 'OOPS Component Test: can run a sub-test or a family of sub-tests',
56
- attr = dict(
57
- run = dict(
58
- values = known_oops_testcomponent_runs,
59
- outcast = [],
57
+ info="OOPS Component Test: can run a sub-test or a family of sub-tests",
58
+ attr=dict(
59
+ run=dict(
60
+ values=known_oops_testcomponent_runs,
61
+ outcast=[],
60
62
  ),
61
63
  ),
62
64
  )
@@ -65,8 +67,8 @@ class OOPSTestComponent(OOPSBinary):
65
67
  """
66
68
  Build command line for execution as a single string.
67
69
  """
68
- cmdline = ''
70
+ cmdline = ""
69
71
  if test_type is not None:
70
- cmdline += '-t {} '.format(test_type)
72
+ cmdline += "-t {} ".format(test_type)
71
73
  cmdline += super().command_line(configfile)
72
74
  return cmdline
@@ -20,16 +20,19 @@ logger = loggers.getLogger(__name__)
20
20
 
21
21
  class BdpeError(Exception):
22
22
  """Base for Bdpe errors."""
23
+
23
24
  pass
24
25
 
25
26
 
26
27
  class BdpeConfigurationError(BdpeError):
27
28
  """Missing BDPE product description."""
29
+
28
30
  pass
29
31
 
30
32
 
31
33
  class BdpeMismatchError(BdpeError):
32
34
  """BDPE product description does not match ressource description."""
35
+
33
36
  pass
34
37
 
35
38
 
@@ -58,71 +61,84 @@ class BdpeProvider(Provider):
58
61
  _footprint = [
59
62
  namespacefp,
60
63
  dict(
61
- info = 'BDPE provider',
62
- attr = dict(
63
- namespace = dict(
64
- default = Namespace('bdpe.archive.fr'),
65
- values = ['bdpe.archive.fr'],
64
+ info="BDPE provider",
65
+ attr=dict(
66
+ namespace=dict(
67
+ default=Namespace("bdpe.archive.fr"),
68
+ values=["bdpe.archive.fr"],
66
69
  ),
67
- bdpeid = dict(
70
+ bdpeid=dict(),
71
+ preferred_target=dict(
72
+ info="The database we'd like to get the data from - See the BDPE documentation.",
73
+ optional=True,
74
+ default=DelayedEnvValue("BDPE_CIBLE_PREFEREE", "SEC"),
75
+ values=[
76
+ "OPER",
77
+ "INT",
78
+ "SEC",
79
+ "oper",
80
+ "int",
81
+ "sec",
82
+ ],
68
83
  ),
69
- preferred_target = dict(
70
- info = "The database we'd like to get the data from - See the BDPE documentation.",
71
- optional = True,
72
- default = DelayedEnvValue('BDPE_CIBLE_PREFEREE', 'SEC'),
73
- values = ['OPER', 'INT', 'SEC',
74
- 'oper', 'int', 'sec', ],
84
+ forbidden_target=dict(
85
+ info="The database we don't want to access - See the BDPE documentation.",
86
+ optional=True,
87
+ default=DelayedEnvValue("BDPE_CIBLE_INTERDITE", "OPER"),
88
+ values=[
89
+ "OPER",
90
+ "INT",
91
+ "SEC",
92
+ "oper",
93
+ "int",
94
+ "sec",
95
+ ],
75
96
  ),
76
- forbidden_target = dict(
77
- info = "The database we don't want to access - See the BDPE documentation.",
78
- optional = True,
79
- default = DelayedEnvValue('BDPE_CIBLE_INTERDITE', 'OPER'),
80
- values = ['OPER', 'INT', 'SEC',
81
- 'oper', 'int', 'sec', ],
97
+ soprano_domain=dict(
98
+ info="Databases priorities profile - See the BDPE documentation.",
99
+ optional=True,
100
+ default=DelayedEnvValue("DOMAINE_SOPRA", "dev"),
101
+ values=["oper", "int", "dev"],
82
102
  ),
83
- soprano_domain = dict(
84
- info = 'Databases priorities profile - See the BDPE documentation.',
85
- optional = True,
86
- default = DelayedEnvValue('DOMAINE_SOPRA', 'dev'),
87
- values = ['oper', 'int', 'dev'],
103
+ allow_archive=dict(
104
+ info="Allow the use of the archive version of the BDPE databases.",
105
+ optional=True,
106
+ type=bool,
107
+ default=False,
88
108
  ),
89
- allow_archive = dict(
90
- info = 'Allow the use of the archive version of the BDPE databases.',
91
- optional = True,
92
- type = bool,
93
- default = False,
109
+ bdpe_timeout=dict(
110
+ info="Seconds before abandoning a request.",
111
+ optional=True,
112
+ type=int,
113
+ default=10,
94
114
  ),
95
- bdpe_timeout = dict(
96
- info = 'Seconds before abandoning a request.',
97
- optional = True,
98
- type = int,
99
- default = 10,
115
+ bdpe_retries=dict(
116
+ info="Number of retries when a request fails.",
117
+ optional=True,
118
+ type=int,
119
+ default=3,
100
120
  ),
101
- bdpe_retries = dict(
102
- info = 'Number of retries when a request fails.',
103
- optional = True,
104
- type = int,
105
- default = 3,
121
+ config=dict(
122
+ info="A ready to use configuration file object for this storage place.",
123
+ type=GenericConfigParser,
124
+ optional=True,
125
+ default=None,
106
126
  ),
107
- config = dict(
108
- info = 'A ready to use configuration file object for this storage place.',
109
- type = GenericConfigParser,
110
- optional = True,
111
- default = None,
112
- ),
113
- inifile = dict(
114
- info = ('The name of the configuration file that will be used (if ' +
115
- '**config** is not provided.'),
116
- optional = True,
117
- default = '@bdpe-map-resources.ini',
127
+ inifile=dict(
128
+ info=(
129
+ "The name of the configuration file that will be used (if "
130
+ + "**config** is not provided."
131
+ ),
132
+ optional=True,
133
+ default="@bdpe-map-resources.ini",
118
134
  ),
119
135
  ),
120
- fastkeys = {'bdpeid'},
121
- )
136
+ fastkeys={"bdpeid"},
137
+ ),
122
138
  ]
123
139
 
124
140
  def __init__(self, *args, **kw):
125
- logger.debug('BDPE provider init %s', self.__class__)
141
+ logger.debug("BDPE provider init %s", self.__class__)
126
142
  super().__init__(*args, **kw)
127
143
  self._actual_config = self.config
128
144
  if self._actual_config is None:
@@ -130,11 +146,11 @@ class BdpeProvider(Provider):
130
146
 
131
147
  @property
132
148
  def realkind(self):
133
- return 'bdpe'
149
+ return "bdpe"
134
150
 
135
151
  def scheme(self, resource):
136
152
  """A dedicated scheme."""
137
- return 'bdpe'
153
+ return "bdpe"
138
154
 
139
155
  def netloc(self, resource):
140
156
  """The actual netloc is the ``namespace`` attribute of the current provider."""
@@ -142,20 +158,26 @@ class BdpeProvider(Provider):
142
158
 
143
159
  def basename(self, resource):
144
160
  """Something like 'BDPE_num+term'."""
145
- myterm = getattr(resource, 'term', Time(0))
161
+ myterm = getattr(resource, "term", Time(0))
146
162
  if int(myterm) < 0:
147
163
  myterm = Time(9000) - myterm
148
- return 'BDPE_{}+{!s}'.format(self.bdpeid, myterm)
164
+ return "BDPE_{}+{!s}".format(self.bdpeid, myterm)
149
165
 
150
166
  def pathname(self, resource):
151
167
  """Something like 'PREFERRED_FORBIDDEN_DOMAIN_ARCHIVE_TIMEOUT_RETRIES/date/'."""
152
168
  try:
153
169
  requested_date = resource.date.vortex()
154
170
  except AttributeError:
155
- requested_date = 'most_recent'
156
- return '{}_{}_{}_{}_{}_{}/{}'.format(
157
- self.preferred_target, self.forbidden_target, self.soprano_domain,
158
- self.allow_archive, self.bdpe_timeout, self.bdpe_retries, requested_date)
171
+ requested_date = "most_recent"
172
+ return "{}_{}_{}_{}_{}_{}/{}".format(
173
+ self.preferred_target,
174
+ self.forbidden_target,
175
+ self.soprano_domain,
176
+ self.allow_archive,
177
+ self.bdpe_timeout,
178
+ self.bdpe_retries,
179
+ requested_date,
180
+ )
159
181
 
160
182
  def uri(self, resource):
161
183
  """
@@ -165,16 +187,19 @@ class BdpeProvider(Provider):
165
187
  # check that the product is described in the configuration file
166
188
  if not self._actual_config.has_section(self.bdpeid):
167
189
  fmt = 'Missing product n°{} in BDPE configuration file\n"{}"'
168
- raise BdpeConfigurationError(fmt.format(self.bdpeid, self.config.file))
190
+ raise BdpeConfigurationError(
191
+ fmt.format(self.bdpeid, self.config.file)
192
+ )
169
193
 
170
194
  # resource description: rely on the footprint_export (also used to JSONise resources).
171
- rsrcdict = {k: str(v)
172
- for k, v in resource.footprint_export().items()}
195
+ rsrcdict = {k: str(v) for k, v in resource.footprint_export().items()}
173
196
 
174
197
  # check the BDPE pairs against the resource's
175
- for (k, v) in self._actual_config.items(self.bdpeid):
198
+ for k, v in self._actual_config.items(self.bdpeid):
176
199
  if k not in rsrcdict:
177
- raise BdpeMismatchError('Missing key "{}" in resource'.format(k))
200
+ raise BdpeMismatchError(
201
+ 'Missing key "{}" in resource'.format(k)
202
+ )
178
203
  if rsrcdict[k] != v:
179
204
  fmt = 'Bad value for key "{}": rsrc="{}" bdpe="{}"'
180
205
  raise BdpeMismatchError(fmt.format(k, rsrcdict[k], v))
vortex/nwp/data/query.py CHANGED
@@ -23,84 +23,66 @@ class Query(StaticResource):
23
23
  _footprint = [
24
24
  gvar,
25
25
  dict(
26
- info = 'Abstract class for queries.',
27
- attr = dict(
28
- gvar = dict(
29
- values = ['extract_stuff'],
30
- default = 'extract_stuff'
31
- ),
32
- source = dict(),
33
- origin = dict(),
26
+ info="Abstract class for queries.",
27
+ attr=dict(
28
+ gvar=dict(values=["extract_stuff"], default="extract_stuff"),
29
+ source=dict(),
30
+ origin=dict(),
34
31
  ),
35
- )
32
+ ),
36
33
  ]
37
34
 
38
35
  def gget_urlquery(self):
39
36
  """GGET specific query : ``extract``."""
40
- return 'extract=' + self.source
37
+ return "extract=" + self.source
41
38
 
42
39
 
43
40
  class BDAPQuery(Query):
44
41
  """Class to deal with BDAP queries."""
42
+
45
43
  _footprint = dict(
46
- info = 'BDAP query',
47
- attr = dict(
48
- kind = dict(
49
- values = ['bdap_query']
50
- ),
51
- origin = dict(
52
- default = 'bdap',
53
- values = ['bdap'],
54
- optional = True
55
- )
56
- )
44
+ info="BDAP query",
45
+ attr=dict(
46
+ kind=dict(values=["bdap_query"]),
47
+ origin=dict(default="bdap", values=["bdap"], optional=True),
48
+ ),
57
49
  )
58
50
 
59
51
  @property
60
52
  def realkind(self):
61
- return 'bdap_query'
53
+ return "bdap_query"
62
54
 
63
55
 
64
56
  class BDMPQuery(Query):
65
57
  """Class to deal with BDMP queries."""
58
+
66
59
  _footprint = dict(
67
- info = 'BDMP query',
68
- attr = dict(
69
- kind = dict(
70
- values = ['bdmp_query']
71
- ),
72
- origin = dict(
73
- default = 'bdmp',
74
- values = ['bdmp'],
75
- optional = True
76
- )
77
- )
60
+ info="BDMP query",
61
+ attr=dict(
62
+ kind=dict(values=["bdmp_query"]),
63
+ origin=dict(default="bdmp", values=["bdmp"], optional=True),
64
+ ),
78
65
  )
79
66
 
80
67
  @property
81
68
  def realkind(self):
82
- return 'bdmp_query'
69
+ return "bdmp_query"
83
70
 
84
71
 
85
72
  class BDCPQuery(Query):
86
73
  """Class to deal with BDCP queries."""
74
+
87
75
  _footprint = dict(
88
- info = 'BDCP query',
89
- attr = dict(
90
- kind = dict(
91
- values = ['bdcp_query']
92
- ),
93
- origin = dict(
94
- default = 'bdcp',
95
- values = ['bdcp'],
96
- optional = True
97
- ),
98
- )
76
+ info="BDCP query",
77
+ attr=dict(
78
+ kind=dict(values=["bdcp_query"]),
79
+ origin=dict(default="bdcp", values=["bdcp"], optional=True),
80
+ ),
99
81
  )
100
82
 
101
83
  @property
102
84
  def realkind(self):
103
- return 'bdcp_query'
85
+ return "bdcp_query"
104
86
 
105
87
 
106
88
  class StaticCutoffDispenser:
@@ -116,8 +98,9 @@ class StaticCutoffDispenser:
116
98
  def __init__(self, default_cutoff, obstype_cutoffs=None):
117
99
  self._default_cutoff = default_cutoff
118
100
  if obstype_cutoffs:
119
- self._cutoffs = {k: {o.lower() for o in v}
120
- for k, v in obstype_cutoffs.items()}
101
+ self._cutoffs = {
102
+ k: {o.lower() for o in v} for k, v in obstype_cutoffs.items()
103
+ }
121
104
  else:
122
105
  self._cutoffs = {}
123
106
 
@@ -150,66 +133,72 @@ class BDMQueryContent(AlmostListContent):
150
133
  information in the BDM query.
151
134
  """
152
135
  if cutoffs_dispenser.max_cutoff is None:
153
- logger.warning("The cutoffs_dispenser is empty. No cutoff data can be retrieved")
136
+ logger.warning(
137
+ "The cutoffs_dispenser is empty. No cutoff data can be retrieved"
138
+ )
154
139
  else:
155
140
  xdata = list()
156
141
  for line in self:
157
142
  xdata.append(line)
158
143
  l_match = self._RE_OBSTYPE.match(line)
159
144
  if l_match:
160
- cutoff_fmt = '{0:s}{1:<' + str(len(l_match.group(2))) + 's}:{2:s}{3.ymdhms:s}\n'
145
+ cutoff_fmt = (
146
+ "{0:s}{1:<"
147
+ + str(len(l_match.group(2)))
148
+ + "s}:{2:s}{3.ymdhms:s}\n"
149
+ )
161
150
  cutoff_date = cutoffs_dispenser(l_match.group(4))
162
- xdata.append(cutoff_fmt.format(l_match.group(1),
163
- 'CUTOFF',
164
- l_match.group(3),
165
- cutoff_date))
166
- logger.info('CUTOFF=%s added for obstype < %s >.',
167
- cutoff_date.ymdhms, l_match.group(4))
151
+ xdata.append(
152
+ cutoff_fmt.format(
153
+ l_match.group(1),
154
+ "CUTOFF",
155
+ l_match.group(3),
156
+ cutoff_date,
157
+ )
158
+ )
159
+ logger.info(
160
+ "CUTOFF=%s added for obstype < %s >.",
161
+ cutoff_date.ymdhms,
162
+ l_match.group(4),
163
+ )
168
164
  self._data = xdata
169
165
 
170
166
 
171
167
  class BDMQuery(Query):
172
168
  """Class to deal with BDM queries."""
169
+
173
170
  _footprint = dict(
174
- info = 'BDM query',
175
- attr = dict(
176
- kind = dict(
177
- values = ['bdm_query']
178
- ),
179
- origin = dict(
180
- default = 'bdm',
181
- values = ['bdm'],
182
- optional = True
183
- ),
171
+ info="BDM query",
172
+ attr=dict(
173
+ kind=dict(values=["bdm_query"]),
174
+ origin=dict(default="bdm", values=["bdm"], optional=True),
184
175
  clscontents=dict(
185
- default = BDMQueryContent,
176
+ default=BDMQueryContent,
186
177
  ),
187
- )
178
+ ),
188
179
  )
189
180
 
190
181
  @property
191
182
  def realkind(self):
192
- return 'bdm_query'
183
+ return "bdm_query"
193
184
 
194
185
 
195
186
  class MarsQuery(Query):
196
187
  """Class to deal with Mars queries"""
197
188
 
198
189
  _footprint = dict(
199
- info = 'Mars query',
200
- attr = dict(
201
- kind = dict(
202
- values = ['mars_query']
203
- ),
204
- origin = dict(
205
- default = "mars",
206
- values = ["mars", ],
207
- optional = True
208
- ),
209
- clscontents=dict(
210
- default = DataTemplate
190
+ info="Mars query",
191
+ attr=dict(
192
+ kind=dict(values=["mars_query"]),
193
+ origin=dict(
194
+ default="mars",
195
+ values=[
196
+ "mars",
197
+ ],
198
+ optional=True,
211
199
  ),
212
- )
200
+ clscontents=dict(default=DataTemplate),
201
+ ),
213
202
  )
214
203
 
215
204
  @property