climate-ref 0.5.1__tar.gz → 0.5.3__tar.gz
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.
- {climate_ref-0.5.1 → climate_ref-0.5.3}/PKG-INFO +12 -8
- {climate_ref-0.5.1 → climate_ref-0.5.3}/README.md +3 -3
- {climate_ref-0.5.1 → climate_ref-0.5.3}/pyproject.toml +7 -2
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/cli/solve.py +14 -1
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/config.py +55 -13
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/database.py +46 -0
- climate_ref-0.5.3/src/climate_ref/dataset_registry/obs4ref_reference.txt +36 -0
- climate_ref-0.5.3/src/climate_ref/dataset_registry/sample_data.txt +105 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/datasets/cmip6.py +87 -2
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/executor/result_handling.py +17 -16
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/migrations/env.py +5 -1
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/provider_registry.py +2 -1
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/solver.py +39 -8
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/testing.py +1 -1
- {climate_ref-0.5.1 → climate_ref-0.5.3}/tests/unit/datasets/test_cmip6.py +14 -1
- climate_ref-0.5.3/tests/unit/datasets/test_obs4mips/obs4mips_catalog_db.yml +720 -0
- climate_ref-0.5.3/tests/unit/datasets/test_obs4mips/obs4mips_catalog_local.yml +756 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/tests/unit/datasets/test_obs4mips.py +44 -28
- climate_ref-0.5.3/tests/unit/datasets/test_pmp_climatology/pmp_catalog_local.yml +756 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/tests/unit/datasets/test_pmp_climatology.py +8 -5
- {climate_ref-0.5.1 → climate_ref-0.5.3}/tests/unit/models/test_metric_value.py +3 -3
- {climate_ref-0.5.1 → climate_ref-0.5.3}/tests/unit/test_config.py +5 -1
- {climate_ref-0.5.1 → climate_ref-0.5.3}/tests/unit/test_database.py +107 -1
- {climate_ref-0.5.1 → climate_ref-0.5.3}/tests/unit/test_solver.py +85 -12
- climate_ref-0.5.1/src/climate_ref/dataset_registry/obs4ref_reference.txt +0 -2
- climate_ref-0.5.1/src/climate_ref/dataset_registry/sample_data.txt +0 -74
- climate_ref-0.5.1/tests/unit/datasets/test_obs4mips/obs4mips_catalog_db.yml +0 -60
- climate_ref-0.5.1/tests/unit/datasets/test_obs4mips/obs4mips_catalog_local.yml +0 -21
- climate_ref-0.5.1/tests/unit/datasets/test_pmp_climatology/pmp_catalog_local.yml +0 -21
- {climate_ref-0.5.1 → climate_ref-0.5.3}/.gitignore +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/Dockerfile +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/LICENCE +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/NOTICE +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/conftest.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/__init__.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/_config_helpers.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/alembic.ini +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/cli/__init__.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/cli/_utils.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/cli/config.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/cli/datasets.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/cli/executions.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/cli/providers.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/constants.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/datasets/__init__.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/datasets/base.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/datasets/obs4mips.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/datasets/pmp_climatology.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/datasets/utils.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/executor/__init__.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/executor/local.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/executor/synchronous.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/migrations/README +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/migrations/script.py.mako +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/migrations/versions/2025-05-02T1418_341a4aa2551e_regenerate.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/migrations/versions/2025-05-09T2032_03dbb4998e49_series_metric_value.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/models/__init__.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/models/base.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/models/dataset.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/models/diagnostic.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/models/execution.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/models/metric_value.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/models/provider.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/src/climate_ref/py.typed +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/tests/unit/cli/test_config.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/tests/unit/cli/test_datasets.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/tests/unit/cli/test_executions/test_inspect.txt +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/tests/unit/cli/test_executions.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/tests/unit/cli/test_providers.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/tests/unit/cli/test_root.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/tests/unit/cli/test_solve.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/tests/unit/datasets/conftest.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/tests/unit/datasets/test_cmip6/cmip6_catalog_db.yml +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/tests/unit/datasets/test_cmip6/cmip6_catalog_local.yml +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/tests/unit/datasets/test_datasets.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/tests/unit/datasets/test_utils.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/tests/unit/executor/test_local_executor.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/tests/unit/executor/test_result_handling.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/tests/unit/executor/test_synchronous_executor.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/tests/unit/models/test_metric_execution.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/tests/unit/test_provider_registry.py +0 -0
- {climate_ref-0.5.1 → climate_ref-0.5.3}/tests/unit/test_solver/test_solve_metrics.yml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: climate-ref
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.3
|
|
4
4
|
Summary: Application which runs the CMIP Rapid Evaluation Framework
|
|
5
5
|
Author-email: Jared Lewis <jared.lewis@climate-resource.com>, Mika Pflueger <mika.pflueger@climate-resource.com>, Bouwe Andela <b.andela@esciencecenter.nl>, Jiwoo Lee <lee1043@llnl.gov>, Min Xu <xum1@ornl.gov>, Nathan Collier <collierno@ornl.gov>, Dora Hegedus <dora.hegedus@stfc.ac.uk>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -30,15 +30,19 @@ Requires-Dist: sqlalchemy>=2.0.36
|
|
|
30
30
|
Requires-Dist: tomlkit>=0.13.2
|
|
31
31
|
Requires-Dist: tqdm>=4.67.1
|
|
32
32
|
Requires-Dist: typer>=0.12.5
|
|
33
|
+
Provides-Extra: aft-providers
|
|
34
|
+
Requires-Dist: climate-ref-esmvaltool>=0.5.0; extra == 'aft-providers'
|
|
35
|
+
Requires-Dist: climate-ref-ilamb>=0.5.0; extra == 'aft-providers'
|
|
36
|
+
Requires-Dist: climate-ref-pmp>=0.5.0; extra == 'aft-providers'
|
|
33
37
|
Provides-Extra: celery
|
|
34
38
|
Requires-Dist: climate-ref-celery>=0.5.0; extra == 'celery'
|
|
35
|
-
Provides-Extra: metrics
|
|
36
|
-
Requires-Dist: climate-ref-esmvaltool>=0.5.0; extra == 'metrics'
|
|
37
|
-
Requires-Dist: climate-ref-ilamb>=0.5.0; extra == 'metrics'
|
|
38
|
-
Requires-Dist: climate-ref-pmp>=0.5.0; extra == 'metrics'
|
|
39
39
|
Provides-Extra: postgres
|
|
40
40
|
Requires-Dist: alembic-postgresql-enum>=1.7.0; extra == 'postgres'
|
|
41
41
|
Requires-Dist: psycopg2-binary>=2.9.2; extra == 'postgres'
|
|
42
|
+
Provides-Extra: providers
|
|
43
|
+
Requires-Dist: climate-ref-esmvaltool>=0.5.0; extra == 'providers'
|
|
44
|
+
Requires-Dist: climate-ref-ilamb>=0.5.0; extra == 'providers'
|
|
45
|
+
Requires-Dist: climate-ref-pmp>=0.5.0; extra == 'providers'
|
|
42
46
|
Description-Content-Type: text/markdown
|
|
43
47
|
|
|
44
48
|
# Climate REF (Rapid Evaluation Framework)
|
|
@@ -64,15 +68,15 @@ pip install climate-ref
|
|
|
64
68
|
If you want to use the diagnostic providers for the Assessment Fast Track, you can install them with:
|
|
65
69
|
|
|
66
70
|
```bash
|
|
67
|
-
pip install climate-ref[
|
|
71
|
+
pip install climate-ref[aft-providers]
|
|
68
72
|
```
|
|
69
73
|
|
|
70
74
|
## Quick Start
|
|
71
75
|
|
|
72
76
|
```bash
|
|
73
77
|
# Ingest some observation datasets
|
|
74
|
-
ref datasets fetch-data --registry obs4ref
|
|
75
|
-
ref datasets fetch-data --registry sample-data
|
|
78
|
+
ref datasets fetch-data --registry obs4ref ---output-directory datasets/obs4ref
|
|
79
|
+
ref datasets fetch-data --registry sample-data ---output-directory datasets/sample-data
|
|
76
80
|
|
|
77
81
|
# Run metrics against your climate data
|
|
78
82
|
ref solve
|
|
@@ -21,15 +21,15 @@ pip install climate-ref
|
|
|
21
21
|
If you want to use the diagnostic providers for the Assessment Fast Track, you can install them with:
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
|
-
pip install climate-ref[
|
|
24
|
+
pip install climate-ref[aft-providers]
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
## Quick Start
|
|
28
28
|
|
|
29
29
|
```bash
|
|
30
30
|
# Ingest some observation datasets
|
|
31
|
-
ref datasets fetch-data --registry obs4ref
|
|
32
|
-
ref datasets fetch-data --registry sample-data
|
|
31
|
+
ref datasets fetch-data --registry obs4ref ---output-directory datasets/obs4ref
|
|
32
|
+
ref datasets fetch-data --registry sample-data ---output-directory datasets/sample-data
|
|
33
33
|
|
|
34
34
|
# Run metrics against your climate data
|
|
35
35
|
ref solve
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "climate-ref"
|
|
3
|
-
version = "0.5.
|
|
3
|
+
version = "0.5.3"
|
|
4
4
|
description = "Application which runs the CMIP Rapid Evaluation Framework"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = [
|
|
@@ -49,7 +49,12 @@ postgres = [
|
|
|
49
49
|
celery = [
|
|
50
50
|
"climate-ref-celery>=0.5.0",
|
|
51
51
|
]
|
|
52
|
-
|
|
52
|
+
aft-providers = [
|
|
53
|
+
"climate-ref-esmvaltool>=0.5.0",
|
|
54
|
+
"climate-ref-pmp>=0.5.0",
|
|
55
|
+
"climate-ref-ilamb>=0.5.0",
|
|
56
|
+
]
|
|
57
|
+
providers = [
|
|
53
58
|
"climate-ref-esmvaltool>=0.5.0",
|
|
54
59
|
"climate-ref-pmp>=0.5.0",
|
|
55
60
|
"climate-ref-ilamb>=0.5.0",
|
|
@@ -10,6 +10,12 @@ def solve(
|
|
|
10
10
|
ctx: typer.Context,
|
|
11
11
|
dry_run: bool = typer.Option(False, help="Do not execute any diagnostics"),
|
|
12
12
|
timeout: int = typer.Option(60, help="Timeout in seconds for the solve operation"),
|
|
13
|
+
one_per_provider: bool = typer.Option(
|
|
14
|
+
False, help="Limit to one execution per provider. This is useful for testing"
|
|
15
|
+
),
|
|
16
|
+
one_per_diagnostic: bool = typer.Option(
|
|
17
|
+
False, help="Limit to one execution per diagnostic. This is useful for testing"
|
|
18
|
+
),
|
|
13
19
|
) -> None:
|
|
14
20
|
"""
|
|
15
21
|
Solve for executions that require recalculation
|
|
@@ -19,4 +25,11 @@ def solve(
|
|
|
19
25
|
"""
|
|
20
26
|
config = ctx.obj.config
|
|
21
27
|
db = ctx.obj.database
|
|
22
|
-
solve_required_executions(
|
|
28
|
+
solve_required_executions(
|
|
29
|
+
config=config,
|
|
30
|
+
db=db,
|
|
31
|
+
dry_run=dry_run,
|
|
32
|
+
timeout=timeout,
|
|
33
|
+
one_per_provider=one_per_provider,
|
|
34
|
+
one_per_diagnostic=one_per_diagnostic,
|
|
35
|
+
)
|
|
@@ -74,11 +74,13 @@ class PathConfig:
|
|
|
74
74
|
/// admonition | Warning
|
|
75
75
|
type: warning
|
|
76
76
|
|
|
77
|
-
These paths must be common across all systems that the REF is being run
|
|
77
|
+
These paths must be common across all systems that the REF is being run.
|
|
78
|
+
Generally, this means that they should be mounted in the same location on all systems.
|
|
78
79
|
///
|
|
79
80
|
|
|
80
81
|
If any of these paths are specified as relative paths,
|
|
81
82
|
they will be resolved to absolute paths.
|
|
83
|
+
These absolute paths will be used for all operations in the REF.
|
|
82
84
|
"""
|
|
83
85
|
|
|
84
86
|
log: Path = env_field(name="LOG_ROOT", converter=ensure_absolute_path)
|
|
@@ -157,12 +159,12 @@ class ExecutorConfig:
|
|
|
157
159
|
|
|
158
160
|
executor: str = env_field(name="EXECUTOR", default="climate_ref.executor.LocalExecutor")
|
|
159
161
|
"""
|
|
160
|
-
Executor to use for running diagnostics
|
|
162
|
+
Executor class to use for running diagnostics
|
|
161
163
|
|
|
162
164
|
This should be the fully qualified name of the executor class
|
|
163
165
|
(e.g. `climate_ref.executor.LocalExecutor`).
|
|
164
|
-
The default is to use the local executor
|
|
165
|
-
|
|
166
|
+
The default is to use the local executor which runs the executions locally, in-parallel
|
|
167
|
+
using a process pool.
|
|
166
168
|
|
|
167
169
|
This class will be used for all executions of diagnostics.
|
|
168
170
|
"""
|
|
@@ -172,6 +174,7 @@ class ExecutorConfig:
|
|
|
172
174
|
Additional configuration for the executor.
|
|
173
175
|
|
|
174
176
|
See the documentation for the executor for the available configuration options.
|
|
177
|
+
These options will be passed to the executor class when it is created.
|
|
175
178
|
"""
|
|
176
179
|
|
|
177
180
|
def build(self, config: "Config", database: "Database") -> Executor:
|
|
@@ -199,7 +202,30 @@ class ExecutorConfig:
|
|
|
199
202
|
@define
|
|
200
203
|
class DiagnosticProviderConfig:
|
|
201
204
|
"""
|
|
202
|
-
|
|
205
|
+
Defining the diagnostic providers used by the REF.
|
|
206
|
+
|
|
207
|
+
Each diagnostic provider is a package that contains the logic for running a specific
|
|
208
|
+
set of diagnostics.
|
|
209
|
+
This configuration determines which diagnostic providers are loaded and used when solving.
|
|
210
|
+
|
|
211
|
+
Multiple diagnostic providers can be specified as shown in the example below.
|
|
212
|
+
|
|
213
|
+
```toml
|
|
214
|
+
[[diagnostic_providers]]
|
|
215
|
+
provider = "climate_ref_esmvaltool.provider"
|
|
216
|
+
|
|
217
|
+
[diagnostic_providers.config]
|
|
218
|
+
|
|
219
|
+
[[diagnostic_providers]]
|
|
220
|
+
provider = "climate_ref_ilamb.provider"
|
|
221
|
+
|
|
222
|
+
[diagnostic_providers.config]
|
|
223
|
+
|
|
224
|
+
[[diagnostic_providers]]
|
|
225
|
+
provider = "climate_ref_pmp.provider"
|
|
226
|
+
|
|
227
|
+
[diagnostic_providers.config]
|
|
228
|
+
```
|
|
203
229
|
"""
|
|
204
230
|
|
|
205
231
|
provider: str
|
|
@@ -224,24 +250,42 @@ class DbConfig:
|
|
|
224
250
|
"""
|
|
225
251
|
Database configuration
|
|
226
252
|
|
|
227
|
-
We
|
|
228
|
-
|
|
253
|
+
We support SQLite and PostgreSQL databases.
|
|
254
|
+
The default is to use SQLite, which is a file-based database that is stored in the
|
|
255
|
+
`REF_CONFIGURATION` directory.
|
|
256
|
+
This is a good option for testing and development, but not recommended for production use.
|
|
257
|
+
|
|
258
|
+
For production use, we recommend using PostgreSQL.
|
|
229
259
|
"""
|
|
230
260
|
|
|
231
261
|
database_url: str = env_field(name="DATABASE_URL")
|
|
232
262
|
"""
|
|
233
263
|
Database URL that describes the connection to the database.
|
|
234
264
|
|
|
235
|
-
Defaults to sqlite:///{config.paths.db}/climate_ref.db
|
|
265
|
+
Defaults to `sqlite:///{config.paths.db}/climate_ref.db`.
|
|
236
266
|
This configuration value will be overridden by the `REF_DATABASE_URL` environment variable.
|
|
237
267
|
|
|
238
|
-
|
|
268
|
+
**Schemas**
|
|
239
269
|
|
|
270
|
+
The following schemas are supported:
|
|
271
|
+
```
|
|
240
272
|
postgresql://USER:PASSWORD@HOST:PORT/NAME
|
|
273
|
+
|
|
241
274
|
sqlite:///RELATIVE_PATH or sqlite:////ABS_PATH or sqlite:///:memory:
|
|
275
|
+
```
|
|
242
276
|
"""
|
|
243
277
|
run_migrations: bool = field(default=True)
|
|
244
278
|
|
|
279
|
+
max_backups: int = env_field(name="MAX_BACKUPS", default=5)
|
|
280
|
+
"""
|
|
281
|
+
Maximum number of database backups to keep.
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
When running migrations for on-disk SQLite databases, a backup of the database is created.
|
|
285
|
+
This setting controls how many of these backups are retained.
|
|
286
|
+
The oldest backups are automatically removed when this limit is exceeded.
|
|
287
|
+
"""
|
|
288
|
+
|
|
245
289
|
@database_url.default
|
|
246
290
|
def _connection_url_factory(self) -> str:
|
|
247
291
|
filename = env.path("REF_CONFIGURATION") / "db" / "climate_ref.db"
|
|
@@ -285,12 +329,10 @@ def _load_config(config_file: str | Path, doc: dict[str, Any]) -> "Config":
|
|
|
285
329
|
return _converter_defaults_relaxed.structure(doc, Config)
|
|
286
330
|
|
|
287
331
|
|
|
288
|
-
@define
|
|
332
|
+
@define(auto_attribs=True)
|
|
289
333
|
class Config:
|
|
290
334
|
"""
|
|
291
|
-
REF
|
|
292
|
-
|
|
293
|
-
This class is used to store the configuration of the REF application.
|
|
335
|
+
Configuration that is used by the REF
|
|
294
336
|
"""
|
|
295
337
|
|
|
296
338
|
log_level: str = field(default="INFO")
|
|
@@ -9,6 +9,8 @@ It provides a session object that can be used to interact with the database and
|
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
11
|
import importlib.resources
|
|
12
|
+
import shutil
|
|
13
|
+
from datetime import datetime
|
|
12
14
|
from pathlib import Path
|
|
13
15
|
from typing import TYPE_CHECKING, Any
|
|
14
16
|
from urllib import parse as urlparse
|
|
@@ -53,6 +55,44 @@ def _get_database_revision(connection: sqlalchemy.engine.Connection) -> str | No
|
|
|
53
55
|
return current_rev
|
|
54
56
|
|
|
55
57
|
|
|
58
|
+
def _create_backup(db_path: Path, max_backups: int) -> Path:
|
|
59
|
+
"""
|
|
60
|
+
Create a backup of the database file
|
|
61
|
+
|
|
62
|
+
Parameters
|
|
63
|
+
----------
|
|
64
|
+
db_path
|
|
65
|
+
Path to the database file
|
|
66
|
+
max_backups
|
|
67
|
+
Maximum number of backups to keep
|
|
68
|
+
|
|
69
|
+
Returns
|
|
70
|
+
-------
|
|
71
|
+
:
|
|
72
|
+
Path to the backup file
|
|
73
|
+
"""
|
|
74
|
+
if not db_path.exists():
|
|
75
|
+
logger.warning(f"Database file {db_path} does not exist, skipping backup")
|
|
76
|
+
return db_path
|
|
77
|
+
|
|
78
|
+
backup_dir = db_path.parent / "backups"
|
|
79
|
+
backup_dir.mkdir(exist_ok=True)
|
|
80
|
+
|
|
81
|
+
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
82
|
+
backup_path = backup_dir / f"{db_path.stem}_{timestamp}{db_path.suffix}"
|
|
83
|
+
|
|
84
|
+
logger.info(f"Creating backup of database at {backup_path}")
|
|
85
|
+
shutil.copy2(db_path, backup_path)
|
|
86
|
+
|
|
87
|
+
# Clean up old backups
|
|
88
|
+
backups = sorted(backup_dir.glob(f"{db_path.stem}_*{db_path.suffix}"), reverse=True)
|
|
89
|
+
for old_backup in backups[max_backups:]:
|
|
90
|
+
logger.info(f"Removing old backup {old_backup}")
|
|
91
|
+
old_backup.unlink()
|
|
92
|
+
|
|
93
|
+
return backup_path
|
|
94
|
+
|
|
95
|
+
|
|
56
96
|
def validate_database_url(database_url: str) -> str:
|
|
57
97
|
"""
|
|
58
98
|
Validate a database URL
|
|
@@ -153,6 +193,12 @@ class Database:
|
|
|
153
193
|
"Please delete your database and start again."
|
|
154
194
|
)
|
|
155
195
|
|
|
196
|
+
# Create backup before running migrations
|
|
197
|
+
split_url = urlparse.urlsplit(self.url)
|
|
198
|
+
if split_url.scheme == "sqlite" and split_url.path != ":memory:":
|
|
199
|
+
db_path = Path(split_url.path[1:])
|
|
200
|
+
_create_backup(db_path, config.db.max_backups)
|
|
201
|
+
|
|
156
202
|
alembic.command.upgrade(self.alembic_config(config), "heads")
|
|
157
203
|
|
|
158
204
|
@staticmethod
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
obs4REF/ECMWF/ERA-20C/mon/psl/gn/v20210727/psl_mon_ERA-20C_PCMDI_gn_190001-201012.nc md5:c100cf25d5681c375cd6c1ee60b678ba
|
|
2
|
+
obs4REF/ECMWF/ERA-20C/mon/ts/gn/v20210727/ts_mon_ERA-20C_PCMDI_gn_190001-201012.nc md5:9ed8dfbb805ed4caa282ed70f873a3a0
|
|
3
|
+
obs4REF/NOAA-ESRL-PSD/20CR/mon/psl/gn/v20210727/psl_mon_20CR_PCMDI_gn_187101-201212.nc md5:570ce90b3afd1d0b31690ae5dbe32d31
|
|
4
|
+
obs4REF/NOAA-ESRL-PSD/20CR/mon/ts/gn/v20210727/ts_mon_20CR_PCMDI_gn_187101-201212.nc md5:e4890cc19ccc5bac29c6b70f28265ff1
|
|
5
|
+
obs4REF/NOAA-NCEI/CMAP-V1902/mon/pr/gn/v20210727/pr_mon_CMAP-V1902_PCMDI_gn_197901-201901.nc md5:9d943d2dd0645850b616820f246aedf3
|
|
6
|
+
obs4REF/MOHC/HadISST-1-1/mon/ts/gn/v20210727/ts_mon_HadISST-1-1_PCMDI_gn_187001-201907.nc md5:99c8691e0f615dc4d79b4fb5e926cc76
|
|
7
|
+
obs4REF/ESSO/TropFlux-1-0/mon/hfls/gn/v20210727/hfls_mon_TropFlux-1-0_PCMDI_gn_197901-201707.nc md5:2f05191d6727068e1500d8d4ed90098a
|
|
8
|
+
obs4REF/ESSO/TropFlux-1-0/mon/hfns/gn/v20210727/hfns_mon_TropFlux-1-0_PCMDI_gn_197901-201707.nc md5:7a9019e51a41d9e4ab1fcfb072d8ca8d
|
|
9
|
+
obs4REF/ESSO/TropFlux-1-0/mon/hfss/gn/v20210727/hfss_mon_TropFlux-1-0_PCMDI_gn_197901-201707.nc md5:1da9d8fe862c61bc49c36c18b6527213
|
|
10
|
+
obs4REF/ESSO/TropFlux-1-0/mon/tas/gn/v20210727/tas_mon_TropFlux-1-0_PCMDI_gn_197901-201707.nc md5:a6057931b5f6bc000a44514a1a8c891f
|
|
11
|
+
obs4REF/ESSO/TropFlux-1-0/mon/tauu/gn/v20210727/tauu_mon_TropFlux-1-0_PCMDI_gn_197901-201707.nc md5:7c73a3deed3403fa9d21caef3a4d988d
|
|
12
|
+
obs4REF/ESSO/TropFlux-1-0/mon/tauv/gn/v20210727/tauv_mon_TropFlux-1-0_PCMDI_gn_197901-201707.nc md5:8abc7a724a7a297826e2f783a4ea14f9
|
|
13
|
+
obs4REF/ESSO/TropFlux-1-0/mon/ts/gn/v20210727/ts_mon_TropFlux-1-0_PCMDI_gn_197901-201707.nc md5:8697d3d7862f6e3b72bb5a161aa75ee8
|
|
14
|
+
obs4REF/ECMWF/ERA-INT/mon/hfls/gn/v20210727/hfls_mon_ERA-INT_PCMDI_gn_197901-201903.nc md5:1ae4587143f05ee81432b3d9960aab63
|
|
15
|
+
obs4REF/ECMWF/ERA-INT/mon/hfss/gn/v20210727/hfss_mon_ERA-INT_PCMDI_gn_197901-201903.nc md5:261f02b8cbce18486548882a11f9aa34
|
|
16
|
+
obs4REF/ECMWF/ERA-INT/mon/hur/gn/v20210727/hur_mon_ERA-INT_PCMDI_gn_198901-201001.nc md5:56fcd2df8ed2879f18b5e8c78134a148
|
|
17
|
+
obs4REF/ECMWF/ERA-INT/mon/hus/gn/v20210727/hus_mon_ERA-INT_PCMDI_gn_198901-201001.nc md5:6f3344d5d936fb84084ac1caf6431016
|
|
18
|
+
obs4REF/ECMWF/ERA-INT/mon/pr/gn/v20210727/pr_mon_ERA-INT_PCMDI_gn_197901-201903.nc md5:92e48c992cde6850d41c52e1778057c2
|
|
19
|
+
obs4REF/ECMWF/ERA-INT/mon/psl/gn/v20210727/psl_mon_ERA-INT_PCMDI_gn_197901-201903.nc md5:7409d0caa4a675436e28085bed12d0c9
|
|
20
|
+
obs4REF/ECMWF/ERA-INT/mon/rlds/gn/v20210727/rlds_mon_ERA-INT_PCMDI_gn_197901-201903.nc md5:dfba31b6b8e6a4924b7b6cfba648715f
|
|
21
|
+
obs4REF/ECMWF/ERA-INT/mon/rlus/gn/v20210727/rlus_mon_ERA-INT_PCMDI_gn_197901-201903.nc md5:94acf2c3bd5f39301148f610722b4590
|
|
22
|
+
obs4REF/ECMWF/ERA-INT/mon/rsds/gn/v20210727/rsds_mon_ERA-INT_PCMDI_gn_197901-201903.nc md5:0a56d7cd3fdf112a37c48433b8cd1e29
|
|
23
|
+
obs4REF/ECMWF/ERA-INT/mon/rsus/gn/v20210727/rsus_mon_ERA-INT_PCMDI_gn_197901-201903.nc md5:ec8f6e9cb64d81a7c0b70fbd7692e133
|
|
24
|
+
obs4REF/ECMWF/ERA-INT/mon/sfcWind/gn/v20210727/sfcWind_mon_ERA-INT_PCMDI_gn_197901-201903.nc md5:8a54a0edef0b9c22ea0b1dd8d5f2dd57
|
|
25
|
+
obs4REF/ECMWF/ERA-INT/mon/ta/gn/v20210727/ta_mon_ERA-INT_PCMDI_gn_198901-201001.nc md5:458b5d536c7314c29f8867a5417a95a1
|
|
26
|
+
obs4REF/ECMWF/ERA-INT/mon/tauu/gn/v20210727/tauu_mon_ERA-INT_PCMDI_gn_197901-201903.nc md5:af86da822ebd76ed3ee0a7e5d5a9912f
|
|
27
|
+
obs4REF/ECMWF/ERA-INT/mon/tauv/gn/v20210727/tauv_mon_ERA-INT_PCMDI_gn_197901-201903.nc md5:87757bbcaff35aef1d685649563ba0a7
|
|
28
|
+
obs4REF/ECMWF/ERA-INT/mon/ts/gn/v20210727/ts_mon_ERA-INT_PCMDI_gn_197901-201903.nc md5:f6a6f2bd8710df95c06dcb910501a771
|
|
29
|
+
obs4REF/ECMWF/ERA-INT/mon/ua/gn/v20210727/ua_mon_ERA-INT_PCMDI_gn_198901-201001.nc md5:054306f777065cf8cf94d44e412510bd
|
|
30
|
+
obs4REF/ECMWF/ERA-INT/mon/uas/gn/v20210727/uas_mon_ERA-INT_PCMDI_gn_197901-201903.nc md5:2b3144fc737c5e3d2aa930c53751ff2b
|
|
31
|
+
obs4REF/ECMWF/ERA-INT/mon/va/gn/v20210727/va_mon_ERA-INT_PCMDI_gn_198901-201001.nc md5:f67ca168d6cd87bfdd4a911eb72dd022
|
|
32
|
+
obs4REF/ECMWF/ERA-INT/mon/vas/gn/v20210727/vas_mon_ERA-INT_PCMDI_gn_197901-201903.nc md5:ac19b48b897cfe839585df4ff0fc4a7b
|
|
33
|
+
obs4REF/ECMWF/ERA-INT/mon/zg/gn/v20210727/zg_mon_ERA-INT_PCMDI_gn_198901-201001.nc md5:d8fb93f31ff4a6370ccee93db82af86c
|
|
34
|
+
obs4REF/NOAA-NCEI/GPCP-2-3/mon/pr/gn/v20210727/pr_mon_GPCP-2-3_PCMDI_gn_197901-201907.nc md5:0877f014868b83547448f96c3e7c83e9
|
|
35
|
+
obs4REF/NASA-GSFC/TRMM-3B43v-7/mon/pr/gn/v20210727/pr_mon_TRMM-3B43v-7_PCMDI_gn_199801-201712.nc md5:b80c9989d358656c781be5ea5a44c64c
|
|
36
|
+
obs4REF/CNES/AVISO-1-0/mon/zos/gn/v20210727/zos_mon_AVISO-1-0_PCMDI_gn_199301-201912.nc md5:91252303cb65548fee5ff42dd3024825
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
CMIP6/C4MIP/CSIRO/ACCESS-ESM1-5/esm-1pct-brch-1000PgC/r1i1p1f1/Amon/tas/gn/v20191206/tas_Amon_ACCESS-ESM1-5_esm-1pct-brch-1000PgC_r1i1p1f1_gn_016801-026812.nc ffef38229e3b69ea703274f174152cfc4886665bb346c1cc604d88f932137828
|
|
2
|
+
CMIP6/C4MIP/CSIRO/ACCESS-ESM1-5/esm-1pct-brch-1000PgC/r1i1p1f1/fx/areacella/gn/v20191206/areacella_fx_ACCESS-ESM1-5_esm-1pct-brch-1000PgC_r1i1p1f1_gn.nc d3292e1af73f8ab0327a4f689f8b4fdd7d818e861d8b78351daf392de15e4409
|
|
3
|
+
CMIP6/C4MIP/MPI-M/MPI-ESM1-2-LR/esm-1pctCO2/r1i1p1f1/Amon/fco2antt/gn/v20190815/fco2antt_Amon_MPI-ESM1-2-LR_esm-1pctCO2_r1i1p1f1_gn_185001-186912.nc c027154d3ef3962584d48e603638754c59f8bb106923cd8523a08db5be67f2a0
|
|
4
|
+
CMIP6/C4MIP/MPI-M/MPI-ESM1-2-LR/esm-1pctCO2/r1i1p1f1/Amon/fco2antt/gn/v20190815/fco2antt_Amon_MPI-ESM1-2-LR_esm-1pctCO2_r1i1p1f1_gn_187001-188912.nc a550c2c36e620eafadba06a6e6f80ff231481b23eb225d9c25874e50122107a9
|
|
5
|
+
CMIP6/C4MIP/MPI-M/MPI-ESM1-2-LR/esm-1pctCO2/r1i1p1f1/Amon/fco2antt/gn/v20190815/fco2antt_Amon_MPI-ESM1-2-LR_esm-1pctCO2_r1i1p1f1_gn_189001-190912.nc 05734f60346b084873772e9b166c136fa5daf1338e8a5a15721e2834389c0cc6
|
|
6
|
+
CMIP6/C4MIP/MPI-M/MPI-ESM1-2-LR/esm-1pctCO2/r1i1p1f1/Amon/fco2antt/gn/v20190815/fco2antt_Amon_MPI-ESM1-2-LR_esm-1pctCO2_r1i1p1f1_gn_191001-191412.nc 82bf8fbcfde0418b4ec95b14af9b653f9b654f748ca1d1deb6450c4ea4ef277c
|
|
7
|
+
CMIP6/C4MIP/MPI-M/MPI-ESM1-2-LR/esm-1pctCO2/r1i1p1f1/Amon/tas/gn/v20190815/tas_Amon_MPI-ESM1-2-LR_esm-1pctCO2_r1i1p1f1_gn_185001-186912.nc f0dcb10542fc6b685238028a333f6255d22b630d588555a7691c26e213267033
|
|
8
|
+
CMIP6/C4MIP/MPI-M/MPI-ESM1-2-LR/esm-1pctCO2/r1i1p1f1/Amon/tas/gn/v20190815/tas_Amon_MPI-ESM1-2-LR_esm-1pctCO2_r1i1p1f1_gn_187001-188912.nc b9cd82588c1a5be0a6eb9b54cb3f6699c9a0f39ce0ce87f59ea8a6ac76c16561
|
|
9
|
+
CMIP6/C4MIP/MPI-M/MPI-ESM1-2-LR/esm-1pctCO2/r1i1p1f1/Amon/tas/gn/v20190815/tas_Amon_MPI-ESM1-2-LR_esm-1pctCO2_r1i1p1f1_gn_189001-190912.nc 5000371d6f31bab096119b000edd5be66b3dbe1b53962ccb01b3105ad449579a
|
|
10
|
+
CMIP6/C4MIP/MPI-M/MPI-ESM1-2-LR/esm-1pctCO2/r1i1p1f1/Amon/tas/gn/v20190815/tas_Amon_MPI-ESM1-2-LR_esm-1pctCO2_r1i1p1f1_gn_191001-191412.nc 9213e72eb6e1e77e7585313838ca245c8ab8f87829ad2e55ba9769df8dde0035
|
|
11
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/1pctCO2/r1i1p1f1/Amon/tas/gn/v20191115/tas_Amon_ACCESS-ESM1-5_1pctCO2_r1i1p1f1_gn_010101-025012.nc b995e36ed0a7d1748901d83359f8995e0d7bfeb1af05ee25e6a376815417ba85
|
|
12
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/1pctCO2/r1i1p1f1/fx/areacella/gn/v20191115/areacella_fx_ACCESS-ESM1-5_1pctCO2_r1i1p1f1_gn.nc f6b1dcf34a6de5c9c0c0743d1f3344923e476e3ad33d73d29da67163b6973d01
|
|
13
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/abrupt-4xCO2/r1i1p1f1/Amon/rlut/gn/v20191115/rlut_Amon_ACCESS-ESM1-5_abrupt-4xCO2_r1i1p1f1_gn_010101-012512.nc d02d4096c7cd1892e284a97d5009e109fce474c2c9e91e43f83ecc9519ae2ce5
|
|
14
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/abrupt-4xCO2/r1i1p1f1/Amon/rsdt/gn/v20191115/rsdt_Amon_ACCESS-ESM1-5_abrupt-4xCO2_r1i1p1f1_gn_010101-012512.nc 14cd0b3ce52c8e11c92cf24ffc70bda191a1da41b0004afdcfbd43d71730d10d
|
|
15
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/abrupt-4xCO2/r1i1p1f1/Amon/rsut/gn/v20191115/rsut_Amon_ACCESS-ESM1-5_abrupt-4xCO2_r1i1p1f1_gn_010101-012512.nc 85c6e81dc193b326646781e5b46d481fa720435b30adf40370a8dc0dd1c49714
|
|
16
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/abrupt-4xCO2/r1i1p1f1/Amon/tas/gn/v20191115/tas_Amon_ACCESS-ESM1-5_abrupt-4xCO2_r1i1p1f1_gn_010101-012512.nc 9469aca1a6d082ae052e0885207acd8b16859aad37d9e0a514c71c7b45419887
|
|
17
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/abrupt-4xCO2/r1i1p1f1/fx/areacella/gn/v20191115/areacella_fx_ACCESS-ESM1-5_abrupt-4xCO2_r1i1p1f1_gn.nc 78f79e91d0fa163e2744aa70c1ac89b8c878a2753ece016110563b6e3c4afd8b
|
|
18
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/historical/r1i1p1f1/Amon/pr/gn/v20191115/pr_Amon_ACCESS-ESM1-5_historical_r1i1p1f1_gn_185001-201412.nc 6696166383b0427476de40658f1d31666a28d9ec2334ffb68be49339e24f49bc
|
|
19
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/historical/r1i1p1f1/Amon/psl/gn/v20191115/psl_Amon_ACCESS-ESM1-5_historical_r1i1p1f1_gn_200001-201412.nc 42c9e8f0d432fe634abab6fe3499854e19ae5ccaf5d70dba6e930aed4c8fd635
|
|
20
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/historical/r1i1p1f1/Amon/rlut/gn/v20191115/rlut_Amon_ACCESS-ESM1-5_historical_r1i1p1f1_gn_200001-201412.nc 019b61b1a05bfc06ef35a1b97e0544d242996c3c1d177ad9da6189e549af0e19
|
|
21
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/historical/r1i1p1f1/Amon/rlutcs/gn/v20191115/rlutcs_Amon_ACCESS-ESM1-5_historical_r1i1p1f1_gn_200501-201412.nc d639634716a12c0af933aa4cbd62edef8e2f1bbab454f3935ed0b1d91d384b63
|
|
22
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/historical/r1i1p1f1/Amon/rsdt/gn/v20191115/rsdt_Amon_ACCESS-ESM1-5_historical_r1i1p1f1_gn_200001-201412.nc dd43eb17caf7082bcc18f31ecd756566466f7fc17ae86284985177ba0ac7d386
|
|
23
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/historical/r1i1p1f1/Amon/rsut/gn/v20191115/rsut_Amon_ACCESS-ESM1-5_historical_r1i1p1f1_gn_200001-201412.nc b3148af8bee4c3562607aeaec9d81d94abad366c85421dd55ef222516fd3f7e0
|
|
24
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/historical/r1i1p1f1/Amon/rsutcs/gn/v20191115/rsutcs_Amon_ACCESS-ESM1-5_historical_r1i1p1f1_gn_200501-201412.nc 9f336ed549c02bf31f73f4679b850463ca8edc4db7afb04b31acd643bc3b51c8
|
|
25
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/historical/r1i1p1f1/Amon/tas/gn/v20191115/tas_Amon_ACCESS-ESM1-5_historical_r1i1p1f1_gn_185001-201412.nc 4c74c74031fbc88cb0df70826e0aea63a582af5f5a714603a0ae70b3ff834097
|
|
26
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/historical/r1i1p1f1/Amon/ts/gn/v20191115/ts_Amon_ACCESS-ESM1-5_historical_r1i1p1f1_gn_200001-201412.nc b3b8e7675287471fd27f3de1f3ecada278eb7ea384da24031d0f3a949e04f757
|
|
27
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/historical/r1i1p1f1/Emon/cSoil/gn/v20191115/cSoil_Emon_ACCESS-ESM1-5_historical_r1i1p1f1_gn_200001-201412.nc d78d9bc532d79a50a0e40645f91572d61a92881aea43552061baea0e77353777
|
|
28
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/historical/r1i1p1f1/Lmon/gpp/gn/v20191115/gpp_Lmon_ACCESS-ESM1-5_historical_r1i1p1f1_gn_200001-201412.nc 41a43edaa1ff7385232f8fbf67fcc551eb77e51ba6cd75b95b5f0ee71af19544
|
|
29
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/historical/r1i1p1f1/Lmon/lai/gn/v20191115/lai_Lmon_ACCESS-ESM1-5_historical_r1i1p1f1_gn_200001-201412.nc 4e6e1530da9030cfb7c207543369c636f339ee3c59c4621e22405494dc436755
|
|
30
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/historical/r1i1p1f1/Lmon/mrro/gn/v20191115/mrro_Lmon_ACCESS-ESM1-5_historical_r1i1p1f1_gn_200001-201412.nc 3b9c010af44ca894bb23a55903fdc57dcd5af8a4e22ea1e98b41b18274720fd9
|
|
31
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/historical/r1i1p1f1/Lmon/mrsos/gn/v20191115/mrsos_Lmon_ACCESS-ESM1-5_historical_r1i1p1f1_gn_200001-201412.nc ca21d4f5341114cbc217d7c30f89c4375b02ea0a2b723d9cb069db6a9c08b08f
|
|
32
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/historical/r1i1p1f1/Lmon/nbp/gn/v20191115/nbp_Lmon_ACCESS-ESM1-5_historical_r1i1p1f1_gn_200001-201412.nc 476b4ebacf38ddb78d44975b01d859e9ca3ed7955b92adc4bd098591867e56b0
|
|
33
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/historical/r1i1p1f1/Ofx/areacello/gn/v20191115/areacello_Ofx_ACCESS-ESM1-5_historical_r1i1p1f1_gn.nc fe5adde7cfe6d80462ad649fe68c2aa983ba700d96cff5ac830b1d7e7b09ca6f
|
|
34
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/historical/r1i1p1f1/Ofx/sftof/gn/v20191115/sftof_Ofx_ACCESS-ESM1-5_historical_r1i1p1f1_gn.nc 89106ad204fb1ac9f3b25f4b93d6fcf9e95db5f1f4466b9baafcb426bad24e4f
|
|
35
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/historical/r1i1p1f1/Omon/msftmz/gn/v20191115/msftmz_Omon_ACCESS-ESM1-5_historical_r1i1p1f1_gn_197901-197912.nc 9016163abd89155710291dc541a4146778f18a320435a2ee618f0da1424b0338
|
|
36
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/historical/r1i1p1f1/Omon/msftmz/gn/v20191115/msftmz_Omon_ACCESS-ESM1-5_historical_r1i1p1f1_gn_198001-198912.nc 97094c32cb3e8f019ad87145d348307c2a57ba9b0acf0cc5c59978213060e8d4
|
|
37
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/historical/r1i1p1f1/Omon/msftmz/gn/v20191115/msftmz_Omon_ACCESS-ESM1-5_historical_r1i1p1f1_gn_199001-199912.nc be682038248b0d79ea9e0402a2a173bd5c054dfdd8cc0932f6cb85d925670889
|
|
38
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/historical/r1i1p1f1/Omon/msftmz/gn/v20191115/msftmz_Omon_ACCESS-ESM1-5_historical_r1i1p1f1_gn_200001-200912.nc 266c386ddfbe9556404afadef1e778a64b5f4c5dd746c54a1beee3e5fbc9954b
|
|
39
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/historical/r1i1p1f1/Omon/msftmz/gn/v20191115/msftmz_Omon_ACCESS-ESM1-5_historical_r1i1p1f1_gn_201001-201412.nc 21fa3a223baced12da8a62ad406ba8126851c3e36589184fba2bb1c8b269c6e3
|
|
40
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/historical/r1i1p1f1/Omon/sos/gn/v20191115/sos_Omon_ACCESS-ESM1-5_historical_r1i1p1f1_gn_197901-201412.nc a757237973708d28f2333542fc34ed9543a15256c7f38d0139fcfe66bdb8d95c
|
|
41
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/historical/r1i1p1f1/Omon/tos/gn/v20191115/tos_Omon_ACCESS-ESM1-5_historical_r1i1p1f1_gn_200001-201412.nc 701fa01ac2c50b622c3454bb3d69a54fed1c92b66f9194c09148b2349aa11342
|
|
42
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/historical/r1i1p1f1/SImon/siconc/gn/v20200817/siconc_SImon_ACCESS-ESM1-5_historical_r1i1p1f1_gn_197901-201412.nc 384b45a0f88678ffaf0c9701a0fc0175fb0c319d7d94d0b3c4334939d653e51d
|
|
43
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/historical/r1i1p1f1/fx/areacella/gn/v20191115/areacella_fx_ACCESS-ESM1-5_historical_r1i1p1f1_gn.nc 6750d4a2432842cb9342ef99b8ecb3569e8ff3dcbbf020f7f9f43a6f7af42f06
|
|
44
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/historical/r1i1p1f1/fx/sftlf/gn/v20191115/sftlf_fx_ACCESS-ESM1-5_historical_r1i1p1f1_gn.nc 08d84ba3cf02a2481b76611dfa1abe25cbf76326003eebc4eb00c99b32fea19a
|
|
45
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/historical/r2i1p1f1/Amon/psl/gn/v20191128/psl_Amon_ACCESS-ESM1-5_historical_r2i1p1f1_gn_200001-201412.nc 0344cf5babc7e3f827d66e1c41a9aaa89b52b6345381bf478146df44c7ec813e
|
|
46
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/historical/r2i1p1f1/Amon/ts/gn/v20191128/ts_Amon_ACCESS-ESM1-5_historical_r2i1p1f1_gn_200001-201412.nc e5dde58ae1b21c765d00dea5e6362c771f6945dcb62def864313c9756ed4b8db
|
|
47
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/historical/r2i1p1f1/fx/areacella/gn/v20191128/areacella_fx_ACCESS-ESM1-5_historical_r2i1p1f1_gn.nc 9a1df5675b2168b3da8e5537f339196ebb8eb73f2dbcf1431f5c269c46191f40
|
|
48
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/piControl/r1i1p1f1/Amon/rlut/gn/v20210316/rlut_Amon_ACCESS-ESM1-5_piControl_r1i1p1f1_gn_010101-012512.nc a8bf35b4415b5d24971fb94f7a04b99ea3534157ea3c1995abf379bad82bbc83
|
|
49
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/piControl/r1i1p1f1/Amon/rsdt/gn/v20210316/rsdt_Amon_ACCESS-ESM1-5_piControl_r1i1p1f1_gn_010101-012512.nc 158cea3284df26fa95851e22bdee4064b909ecd87e12acd52aec242df7171e49
|
|
50
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/piControl/r1i1p1f1/Amon/rsut/gn/v20210316/rsut_Amon_ACCESS-ESM1-5_piControl_r1i1p1f1_gn_010101-012512.nc 5a8f026e4be636e51625a6b59e504de6ed2dfcfae1df8be60084fdf1d602fc1c
|
|
51
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/piControl/r1i1p1f1/Amon/tas/gn/v20210316/tas_Amon_ACCESS-ESM1-5_piControl_r1i1p1f1_gn_010101-018012.nc e8705dda0c26cad086526d8e77f10a91707187e371d90f5ebb7feb4187cec2b4
|
|
52
|
+
CMIP6/CMIP/CSIRO/ACCESS-ESM1-5/piControl/r1i1p1f1/fx/areacella/gn/v20210316/areacella_fx_ACCESS-ESM1-5_piControl_r1i1p1f1_gn.nc c3f274b147fbcb7e7c6116a933a40993c4f2186952b8e8fd4ad8056326688887
|
|
53
|
+
CMIP6/CMIP/MPI-M/MPI-ESM1-2-LR/esm-piControl/r1i1p1f1/Amon/tas/gn/v20190815/tas_Amon_MPI-ESM1-2-LR_esm-piControl_r1i1p1f1_gn_185001-186912.nc 141a24094d42fe2bc0b765774905c192d77817620da273b7e7c789510d0891c9
|
|
54
|
+
CMIP6/CMIP/MPI-M/MPI-ESM1-2-LR/esm-piControl/r1i1p1f1/Amon/tas/gn/v20190815/tas_Amon_MPI-ESM1-2-LR_esm-piControl_r1i1p1f1_gn_187001-188912.nc 5f0dc6bee4c4eb12a05c532fb0ca08aaacbb869b43306c8b82f4bdd6adc661a4
|
|
55
|
+
CMIP6/CMIP/MPI-M/MPI-ESM1-2-LR/esm-piControl/r1i1p1f1/Amon/tas/gn/v20190815/tas_Amon_MPI-ESM1-2-LR_esm-piControl_r1i1p1f1_gn_189001-190912.nc ae9193e06aec8a7f63f2f7ec63fec9d25b2c1dc5de2bbe7065428c722090f45c
|
|
56
|
+
CMIP6/CMIP/MPI-M/MPI-ESM1-2-LR/esm-piControl/r1i1p1f1/Amon/tas/gn/v20190815/tas_Amon_MPI-ESM1-2-LR_esm-piControl_r1i1p1f1_gn_191001-191512.nc 2113b7d4a781c7c28de55b0ffe99c42b49692d113f5109e7a4d0214211a9eb1c
|
|
57
|
+
CMIP6/CMIP/MPI-M/MPI-ESM1-2-LR/esm-piControl/r1i1p1f1/fx/areacella/gn/v20190815/areacella_fx_MPI-ESM1-2-LR_esm-piControl_r1i1p1f1_gn.nc 2f5595635a566d5b4a889468f687aabf99ca5cdadb11f6a770d05d09775bfabb
|
|
58
|
+
CMIP6/DAMIP/CSIRO/ACCESS-ESM1-5/hist-GHG/r1i1p1f1/Amon/psl/gn/v20200615/psl_Amon_ACCESS-ESM1-5_hist-GHG_r1i1p1f1_gn_200001-202012.nc 5fed6b48717fcf508e8b5936be304db0346362c2182c5d13a141afe7c982021a
|
|
59
|
+
CMIP6/DAMIP/CSIRO/ACCESS-ESM1-5/hist-GHG/r1i1p1f1/Amon/ts/gn/v20200615/ts_Amon_ACCESS-ESM1-5_hist-GHG_r1i1p1f1_gn_200001-202012.nc aa98fa93ef29ea266a94d87876b4ae08917caf77e38c5df1eae1ec98a5f559cb
|
|
60
|
+
CMIP6/DAMIP/CSIRO/ACCESS-ESM1-5/hist-GHG/r1i1p1f1/fx/areacella/gn/v20200615/areacella_fx_ACCESS-ESM1-5_hist-GHG_r1i1p1f1_gn.nc 7179f75ff1754e9666b10f8c5508040bbe9fdac0c8117a9231ba5977d4889f27
|
|
61
|
+
CMIP6/DAMIP/CSIRO/ACCESS-ESM1-5/hist-GHG/r2i1p1f1/Amon/psl/gn/v20200615/psl_Amon_ACCESS-ESM1-5_hist-GHG_r2i1p1f1_gn_200001-202012.nc 2073711f1517b53f2670f939b3ad8c81f24ae8d022bd193157e173733eb19636
|
|
62
|
+
CMIP6/DAMIP/CSIRO/ACCESS-ESM1-5/hist-GHG/r2i1p1f1/Amon/ts/gn/v20200615/ts_Amon_ACCESS-ESM1-5_hist-GHG_r2i1p1f1_gn_200001-202012.nc dd8b8043a058454c6218d3895ffd12d3d8cfc2ccef485ece30c913ecc2244d57
|
|
63
|
+
CMIP6/DAMIP/CSIRO/ACCESS-ESM1-5/hist-GHG/r2i1p1f1/fx/areacella/gn/v20200615/areacella_fx_ACCESS-ESM1-5_hist-GHG_r2i1p1f1_gn.nc 6a25555c13d62859cb81f739f24398ae4f1dae60d495d8ada5f799411471985b
|
|
64
|
+
CMIP6/ScenarioMIP/CSIRO/ACCESS-ESM1-5/ssp126/r1i1p1f1/Amon/pr/gn/v20210318/pr_Amon_ACCESS-ESM1-5_ssp126_r1i1p1f1_gn_201501-210012.nc 3650d30ce27d44a0564ee29fd5e4741a60fe7e91ea634f4f6896f3fc494c1cd7
|
|
65
|
+
CMIP6/ScenarioMIP/CSIRO/ACCESS-ESM1-5/ssp126/r1i1p1f1/Amon/rsdt/gn/v20210318/rsdt_Amon_ACCESS-ESM1-5_ssp126_r1i1p1f1_gn_201501-202512.nc 9a04641b91da68be60e307cd1b3e6af72098ae09e5d16103910368314ebf6217
|
|
66
|
+
CMIP6/ScenarioMIP/CSIRO/ACCESS-ESM1-5/ssp126/r1i1p1f1/Amon/rsut/gn/v20210318/rsut_Amon_ACCESS-ESM1-5_ssp126_r1i1p1f1_gn_201501-202512.nc 61aee51691b9e5b4a9d1189bdd59a8dd206ad5e8d554c5ea5e47827e0fd9216a
|
|
67
|
+
CMIP6/ScenarioMIP/CSIRO/ACCESS-ESM1-5/ssp126/r1i1p1f1/Amon/tas/gn/v20210318/tas_Amon_ACCESS-ESM1-5_ssp126_r1i1p1f1_gn_201501-210012.nc b164b974798624b284ac83425fc02f42ae88d75071d76aa3b860253f527ce27f
|
|
68
|
+
CMIP6/ScenarioMIP/CSIRO/ACCESS-ESM1-5/ssp126/r1i1p1f1/Omon/tos/gn/v20210318/tos_Omon_ACCESS-ESM1-5_ssp126_r1i1p1f1_gn_201501-202512.nc 8138c9e1d5ba641799b547b0867fa0068902c17b95277cd26bec1c7e91c7eb0c
|
|
69
|
+
CMIP6/ScenarioMIP/CSIRO/ACCESS-ESM1-5/ssp126/r1i1p1f1/fx/areacella/gn/v20210318/areacella_fx_ACCESS-ESM1-5_ssp126_r1i1p1f1_gn.nc 0b3daf08cacf722fe51e01dd106f0df2fa86b11764befcf26a55d2e670db74df
|
|
70
|
+
obs4REF/obs4REF/CNES/AVISO-1-0/mon/zos/gn/v20210727/zos_mon_AVISO-1-0_PCMDI_gn_199301-201912.nc 1b0a61ea75fbc12a0c8f5ed64c62ddd52c14b30a2873b4977584899c879b66c2
|
|
71
|
+
obs4REF/obs4REF/ECMWF/ERA-20C/mon/psl/gn/v20210727/psl_mon_ERA-20C_PCMDI_gn_190001-201012.nc a307849fa2ef38954400ecef089438400a98e2ba38806c36529ac4b7b91c11a5
|
|
72
|
+
obs4REF/obs4REF/ECMWF/ERA-20C/mon/ts/gn/v20210727/ts_mon_ERA-20C_PCMDI_gn_190001-201012.nc e75d22c2cd5077cc4ced12526f280248b3ab251b0995b830f2f6d716a165af3f
|
|
73
|
+
obs4REF/obs4REF/ECMWF/ERA-INT/mon/hfls/gn/v20210727/hfls_mon_ERA-INT_PCMDI_gn_197901-201903.nc c51b850dccfa4a95d4cbd9555a333aef6f6299191a5a6ccf5a8dec0b3ba389a4
|
|
74
|
+
obs4REF/obs4REF/ECMWF/ERA-INT/mon/hfss/gn/v20210727/hfss_mon_ERA-INT_PCMDI_gn_197901-201903.nc 11f12bb01d71a8d769099fff0f2ff41a2c01a967ce6ab5eb4ef4f691f669de80
|
|
75
|
+
obs4REF/obs4REF/ECMWF/ERA-INT/mon/hur/gn/v20210727/hur_mon_ERA-INT_PCMDI_gn_198901-201001.nc 06b9290fef6dbd9bd776a428429309aed88c32faf2ddae2c3076c817d22ca75b
|
|
76
|
+
obs4REF/obs4REF/ECMWF/ERA-INT/mon/hus/gn/v20210727/hus_mon_ERA-INT_PCMDI_gn_198901-201001.nc 97af286fe733dcf33144517034df92803b80057fecbda488a576a60515763d62
|
|
77
|
+
obs4REF/obs4REF/ECMWF/ERA-INT/mon/pr/gn/v20210727/pr_mon_ERA-INT_PCMDI_gn_197901-201903.nc 7f663506b2984a98b952efc0cae7c2165d5b201884480462672d219e1ac03c13
|
|
78
|
+
obs4REF/obs4REF/ECMWF/ERA-INT/mon/psl/gn/v20210727/psl_mon_ERA-INT_PCMDI_gn_197901-201903.nc 7b9e6aeafe4926fa2435fcf0f8cb0a4afcbfc9aa8db47187e21d5f280879e0ec
|
|
79
|
+
obs4REF/obs4REF/ECMWF/ERA-INT/mon/rlds/gn/v20210727/rlds_mon_ERA-INT_PCMDI_gn_197901-201903.nc d20e0f45fe49252982afbd281980764cac4d3d2aec93e6c18f0f88f30382397c
|
|
80
|
+
obs4REF/obs4REF/ECMWF/ERA-INT/mon/rlus/gn/v20210727/rlus_mon_ERA-INT_PCMDI_gn_197901-201903.nc ba7f248c2dd60f4ce52bb34390c133f2ff73f507476899c6430ba88fa0e92baf
|
|
81
|
+
obs4REF/obs4REF/ECMWF/ERA-INT/mon/rsds/gn/v20210727/rsds_mon_ERA-INT_PCMDI_gn_197901-201903.nc b37c38913868538c6ef1aed10c80c0492dc83cf897073c7bcfd820f716f69db1
|
|
82
|
+
obs4REF/obs4REF/ECMWF/ERA-INT/mon/rsus/gn/v20210727/rsus_mon_ERA-INT_PCMDI_gn_197901-201903.nc 4840ef8fdce03ed7397756d5cbc445949bfce2e64e4f469559eefc0acb0bfd53
|
|
83
|
+
obs4REF/obs4REF/ECMWF/ERA-INT/mon/sfcWind/gn/v20210727/sfcWind_mon_ERA-INT_PCMDI_gn_197901-201903.nc 0e96f90f858cdcd394a6c75c37bd5cf16f8629c46a7ff7e160141c216812eb4f
|
|
84
|
+
obs4REF/obs4REF/ECMWF/ERA-INT/mon/ta/gn/v20210727/ta_mon_ERA-INT_PCMDI_gn_198901-201001.nc d8024c2a148d9c096bb89a6ab7cf88a4857d6368bd87b3b2e8ec2d9e6f99259c
|
|
85
|
+
obs4REF/obs4REF/ECMWF/ERA-INT/mon/tauu/gn/v20210727/tauu_mon_ERA-INT_PCMDI_gn_197901-201903.nc a89e8f5bc93ceca4f73eaab3320836ec29396125ae66df2ba8f55053dd7127fe
|
|
86
|
+
obs4REF/obs4REF/ECMWF/ERA-INT/mon/tauv/gn/v20210727/tauv_mon_ERA-INT_PCMDI_gn_197901-201903.nc 6879b06537c0bb899171f26594e80a4e83b6c5ff70e4304811bf5f334f841a91
|
|
87
|
+
obs4REF/obs4REF/ECMWF/ERA-INT/mon/ts/gn/v20210727/ts_mon_ERA-INT_PCMDI_gn_197901-201903.nc f37fae9b17febbe259044c8652798a94ed50549603dbd2bd0d481c8838bc8f7d
|
|
88
|
+
obs4REF/obs4REF/ECMWF/ERA-INT/mon/ua/gn/v20210727/ua_mon_ERA-INT_PCMDI_gn_198901-201001.nc 988cc905d04e6aa0278d915dd1873242277fca5901c82b3e674e4775bfe71da7
|
|
89
|
+
obs4REF/obs4REF/ECMWF/ERA-INT/mon/uas/gn/v20210727/uas_mon_ERA-INT_PCMDI_gn_197901-201903.nc c104226c7c8cb3ba1c0a75e848eb1c4ad33f4337c283b96daf9a565ead018283
|
|
90
|
+
obs4REF/obs4REF/ECMWF/ERA-INT/mon/va/gn/v20210727/va_mon_ERA-INT_PCMDI_gn_198901-201001.nc 1549f008a6ee6a1d2c8b76f9094328acd296a220cc36e39eb40e4ec345db7785
|
|
91
|
+
obs4REF/obs4REF/ECMWF/ERA-INT/mon/vas/gn/v20210727/vas_mon_ERA-INT_PCMDI_gn_197901-201903.nc 366d6726c8e8f998a4c51eaf9e3905f915cd269171b491afaedf0581d28be2a5
|
|
92
|
+
obs4REF/obs4REF/ECMWF/ERA-INT/mon/zg/gn/v20210727/zg_mon_ERA-INT_PCMDI_gn_198901-201001.nc 60083418a6597e41d9d9b4f80f3731db2c93d065b4ed9113383470a3090943fc
|
|
93
|
+
obs4REF/obs4REF/ESSO/TropFlux-1-0/mon/hfls/gn/v20210727/hfls_mon_TropFlux-1-0_PCMDI_gn_197901-201707.nc c05111c9b0680c52b0f78a0f0603c204130d941527f079ba6c431c35b81d1b09
|
|
94
|
+
obs4REF/obs4REF/ESSO/TropFlux-1-0/mon/hfns/gn/v20210727/hfns_mon_TropFlux-1-0_PCMDI_gn_197901-201707.nc 0f47f55514cb6ac29d8903775cd5af197ccb828d3eb9403eb94c71bdc5a08fc4
|
|
95
|
+
obs4REF/obs4REF/ESSO/TropFlux-1-0/mon/hfss/gn/v20210727/hfss_mon_TropFlux-1-0_PCMDI_gn_197901-201707.nc 1fc71a0befc05e29295025b4f2a1d3030000991ce54ffd5e4e57b513af74f9f5
|
|
96
|
+
obs4REF/obs4REF/ESSO/TropFlux-1-0/mon/tas/gn/v20210727/tas_mon_TropFlux-1-0_PCMDI_gn_197901-201707.nc 8ac0c77ebc9672401bebfc599b7535696eead0c75f4f40ffa735be802b5d6a62
|
|
97
|
+
obs4REF/obs4REF/ESSO/TropFlux-1-0/mon/tauu/gn/v20210727/tauu_mon_TropFlux-1-0_PCMDI_gn_197901-201707.nc b073ed8f915064cf69daeb51d5c31b1167ca8f1ac1f5d4f324ecdfd5847827c6
|
|
98
|
+
obs4REF/obs4REF/ESSO/TropFlux-1-0/mon/tauv/gn/v20210727/tauv_mon_TropFlux-1-0_PCMDI_gn_197901-201707.nc f9b27f56e08dbccec19aa33ac70f1f04bd51eac4d1fa7554c237676b7a3411e2
|
|
99
|
+
obs4REF/obs4REF/ESSO/TropFlux-1-0/mon/ts/gn/v20210727/ts_mon_TropFlux-1-0_PCMDI_gn_197901-201707.nc 8c8857d8dca575d7b2e9cfd7130cfe6172d96e41614ed3666cbfbdb4af9fbdda
|
|
100
|
+
obs4REF/obs4REF/MOHC/HadISST-1-1/mon/ts/gn/v20210727/ts_mon_HadISST-1-1_PCMDI_gn_187001-201907.nc f5cc77d002cd90dc63c63a4db62863fcbf72763d02ae7ba743ff691fe3b10fe3
|
|
101
|
+
obs4REF/obs4REF/NASA-GSFC/TRMM-3B43v-7/mon/pr/gn/v20210727/pr_mon_TRMM-3B43v-7_PCMDI_gn_199801-201712.nc 5df3a5cb29bb08f317dda64bd3659d81c382d69c29d1325f461cbcb0272eb5bc
|
|
102
|
+
obs4REF/obs4REF/NOAA-ESRL-PSD/20CR/mon/psl/gn/v20210727/psl_mon_20CR_PCMDI_gn_187101-201212.nc 47c894191e9a9f62d4c455721ff6bf1a5ab1571082b5a08a2c52ff1240b77ac3
|
|
103
|
+
obs4REF/obs4REF/NOAA-ESRL-PSD/20CR/mon/ts/gn/v20210727/ts_mon_20CR_PCMDI_gn_187101-201212.nc c9a4a75c3df7c24e5662756a7ca8674af8275244ea9fe213384d1a1e41e1bbad
|
|
104
|
+
obs4REF/obs4REF/NOAA-NCEI/CMAP-V1902/mon/pr/gn/v20210727/pr_mon_CMAP-V1902_PCMDI_gn_197901-201901.nc 0a73fa7fef1f631321f2cb70a6aea12c9cc2a2ed00e6cb5d8c03618fe6c9f2ae
|
|
105
|
+
obs4REF/obs4REF/NOAA-NCEI/GPCP-2-3/mon/pr/gn/v20210727/pr_mon_GPCP-2-3_PCMDI_gn_197901-201907.nc dcca502f8748a73b0be5c6e402e14086f1d45e5c85be3cbbe63ba6c07ab0eb21
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import traceback
|
|
3
4
|
import warnings
|
|
4
5
|
from datetime import datetime
|
|
5
6
|
from pathlib import Path
|
|
6
7
|
from typing import Any
|
|
7
8
|
|
|
8
|
-
import ecgtools.parsers
|
|
9
9
|
import pandas as pd
|
|
10
|
+
import xarray as xr
|
|
10
11
|
from ecgtools import Builder
|
|
12
|
+
from ecgtools.parsers.utilities import extract_attr_with_regex # type: ignore
|
|
13
|
+
from loguru import logger
|
|
11
14
|
|
|
12
15
|
from climate_ref.datasets.base import DatasetAdapter
|
|
13
16
|
from climate_ref.models.dataset import CMIP6Dataset
|
|
@@ -65,6 +68,88 @@ def _clean_branch_time(branch_time: pd.Series[str]) -> pd.Series[float]:
|
|
|
65
68
|
return pd.to_numeric(branch_time.astype(str).str.replace("D", ""), errors="coerce")
|
|
66
69
|
|
|
67
70
|
|
|
71
|
+
def parse_cmip6(file: str) -> dict[str, Any]:
|
|
72
|
+
"""
|
|
73
|
+
Parser for CMIP6
|
|
74
|
+
|
|
75
|
+
This function parses the CMIP6 dataset and returns a dictionary with the metadata.
|
|
76
|
+
This was copied from the ecgtools package, but we want to log the exception when it fails.
|
|
77
|
+
"""
|
|
78
|
+
keys = sorted(
|
|
79
|
+
{
|
|
80
|
+
"activity_id",
|
|
81
|
+
"branch_method",
|
|
82
|
+
"branch_time_in_child",
|
|
83
|
+
"branch_time_in_parent",
|
|
84
|
+
"experiment",
|
|
85
|
+
"experiment_id",
|
|
86
|
+
"frequency",
|
|
87
|
+
"grid",
|
|
88
|
+
"grid_label",
|
|
89
|
+
"institution_id",
|
|
90
|
+
"nominal_resolution",
|
|
91
|
+
"parent_activity_id",
|
|
92
|
+
"parent_experiment_id",
|
|
93
|
+
"parent_source_id",
|
|
94
|
+
"parent_time_units",
|
|
95
|
+
"parent_variant_label",
|
|
96
|
+
"realm",
|
|
97
|
+
"product",
|
|
98
|
+
"source_id",
|
|
99
|
+
"source_type",
|
|
100
|
+
"sub_experiment",
|
|
101
|
+
"sub_experiment_id",
|
|
102
|
+
"table_id",
|
|
103
|
+
"variable_id",
|
|
104
|
+
"variant_label",
|
|
105
|
+
}
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
try:
|
|
109
|
+
with xr.open_dataset(file, chunks={}, use_cftime=True) as ds:
|
|
110
|
+
info = {key: ds.attrs.get(key) for key in keys}
|
|
111
|
+
info["member_id"] = info["variant_label"]
|
|
112
|
+
|
|
113
|
+
variable_id = info["variable_id"]
|
|
114
|
+
if variable_id: # pragma: no branch
|
|
115
|
+
attrs = ds[variable_id].attrs
|
|
116
|
+
for attr in ["standard_name", "long_name", "units"]:
|
|
117
|
+
info[attr] = attrs.get(attr)
|
|
118
|
+
|
|
119
|
+
# Set the default of # of vertical levels to 1
|
|
120
|
+
vertical_levels = 1
|
|
121
|
+
start_time, end_time = None, None
|
|
122
|
+
init_year = None
|
|
123
|
+
try:
|
|
124
|
+
vertical_levels = ds[ds.cf["vertical"].name].size
|
|
125
|
+
except (KeyError, AttributeError, ValueError):
|
|
126
|
+
...
|
|
127
|
+
|
|
128
|
+
try:
|
|
129
|
+
start_time, end_time = str(ds.cf["T"][0].data), str(ds.cf["T"][-1].data)
|
|
130
|
+
except (KeyError, AttributeError, ValueError):
|
|
131
|
+
...
|
|
132
|
+
if info.get("sub_experiment_id"): # pragma: no branch
|
|
133
|
+
init_year = extract_attr_with_regex(info["sub_experiment_id"], r"\d{4}")
|
|
134
|
+
if init_year: # pragma: no cover
|
|
135
|
+
init_year = int(init_year)
|
|
136
|
+
info["vertical_levels"] = vertical_levels
|
|
137
|
+
info["init_year"] = init_year
|
|
138
|
+
info["start_time"] = start_time
|
|
139
|
+
info["end_time"] = end_time
|
|
140
|
+
if not (start_time and end_time):
|
|
141
|
+
info["time_range"] = None
|
|
142
|
+
else:
|
|
143
|
+
info["time_range"] = f"{start_time}-{end_time}"
|
|
144
|
+
info["path"] = str(file)
|
|
145
|
+
info["version"] = extract_attr_with_regex(str(file), regex=r"v\d{4}\d{2}\d{2}|v\d{1}") or "v0"
|
|
146
|
+
return info
|
|
147
|
+
|
|
148
|
+
except Exception:
|
|
149
|
+
logger.exception(f"Failed to parse {file}")
|
|
150
|
+
return {"INVALID_ASSET": file, "TRACEBACK": traceback.format_exc()}
|
|
151
|
+
|
|
152
|
+
|
|
68
153
|
class CMIP6DatasetAdapter(DatasetAdapter):
|
|
69
154
|
"""
|
|
70
155
|
Adapter for CMIP6 datasets
|
|
@@ -171,7 +256,7 @@ class CMIP6DatasetAdapter(DatasetAdapter):
|
|
|
171
256
|
depth=10,
|
|
172
257
|
include_patterns=["*.nc"],
|
|
173
258
|
joblib_parallel_kwargs={"n_jobs": self.n_jobs},
|
|
174
|
-
).build(parsing_func=
|
|
259
|
+
).build(parsing_func=parse_cmip6) # type: ignore
|
|
175
260
|
|
|
176
261
|
datasets: pd.DataFrame = builder.df.drop(["init_year"], axis=1)
|
|
177
262
|
|
|
@@ -133,24 +133,25 @@ def handle_execution_result(
|
|
|
133
133
|
# execution.mark_failed()
|
|
134
134
|
|
|
135
135
|
# Perform a bulk insert of scalar values
|
|
136
|
-
# TODO: The section below will likely fail until we have agreed on a controlled vocabulary
|
|
137
136
|
# The current implementation will swallow the exception, but display a log message
|
|
138
137
|
try:
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
138
|
+
scalar_values = [
|
|
139
|
+
{
|
|
140
|
+
"execution_id": execution.id,
|
|
141
|
+
"value": result.value,
|
|
142
|
+
"attributes": result.attributes,
|
|
143
|
+
**result.dimensions,
|
|
144
|
+
}
|
|
145
|
+
for result in cmec_metric_bundle.iter_results()
|
|
146
|
+
]
|
|
147
|
+
if scalar_values:
|
|
148
|
+
# Perform this in a nested transaction to rollback if something goes wrong
|
|
149
|
+
# We will lose the metric values for a given execution, but not the whole execution
|
|
150
|
+
with database.session.begin_nested():
|
|
151
|
+
database.session.execute(
|
|
152
|
+
insert(ScalarMetricValue),
|
|
153
|
+
scalar_values,
|
|
154
|
+
)
|
|
154
155
|
except Exception:
|
|
155
156
|
# TODO: Remove once we have settled on a controlled vocabulary
|
|
156
157
|
logger.exception("Something went wrong when ingesting diagnostic values")
|