esgvoc 2.0.2__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.
- esgvoc/__init__.py +3 -0
- esgvoc/api/__init__.py +91 -0
- esgvoc/api/data_descriptors/EMD_models/__init__.py +66 -0
- esgvoc/api/data_descriptors/EMD_models/arrangement.py +21 -0
- esgvoc/api/data_descriptors/EMD_models/calendar.py +5 -0
- esgvoc/api/data_descriptors/EMD_models/cell_variable_type.py +20 -0
- esgvoc/api/data_descriptors/EMD_models/component_type.py +5 -0
- esgvoc/api/data_descriptors/EMD_models/coordinate.py +52 -0
- esgvoc/api/data_descriptors/EMD_models/grid_mapping.py +19 -0
- esgvoc/api/data_descriptors/EMD_models/grid_region.py +19 -0
- esgvoc/api/data_descriptors/EMD_models/grid_type.py +19 -0
- esgvoc/api/data_descriptors/EMD_models/horizontal_computational_grid.py +56 -0
- esgvoc/api/data_descriptors/EMD_models/horizontal_grid_cells.py +230 -0
- esgvoc/api/data_descriptors/EMD_models/horizontal_subgrid.py +41 -0
- esgvoc/api/data_descriptors/EMD_models/horizontal_units.py +5 -0
- esgvoc/api/data_descriptors/EMD_models/model.py +139 -0
- esgvoc/api/data_descriptors/EMD_models/model_component.py +115 -0
- esgvoc/api/data_descriptors/EMD_models/reference.py +61 -0
- esgvoc/api/data_descriptors/EMD_models/resolution.py +48 -0
- esgvoc/api/data_descriptors/EMD_models/temporal_refinement.py +19 -0
- esgvoc/api/data_descriptors/EMD_models/truncation_method.py +17 -0
- esgvoc/api/data_descriptors/EMD_models/vertical_computational_grid.py +91 -0
- esgvoc/api/data_descriptors/EMD_models/vertical_coordinate.py +5 -0
- esgvoc/api/data_descriptors/EMD_models/vertical_units.py +19 -0
- esgvoc/api/data_descriptors/__init__.py +159 -0
- esgvoc/api/data_descriptors/activity.py +72 -0
- esgvoc/api/data_descriptors/archive.py +5 -0
- esgvoc/api/data_descriptors/area_label.py +30 -0
- esgvoc/api/data_descriptors/branded_suffix.py +30 -0
- esgvoc/api/data_descriptors/branded_variable.py +21 -0
- esgvoc/api/data_descriptors/citation_url.py +5 -0
- esgvoc/api/data_descriptors/contact.py +5 -0
- esgvoc/api/data_descriptors/conventions.py +28 -0
- esgvoc/api/data_descriptors/creation_date.py +18 -0
- esgvoc/api/data_descriptors/data_descriptor.py +127 -0
- esgvoc/api/data_descriptors/data_specs_version.py +25 -0
- esgvoc/api/data_descriptors/date.py +5 -0
- esgvoc/api/data_descriptors/directory_date.py +22 -0
- esgvoc/api/data_descriptors/drs_specs.py +38 -0
- esgvoc/api/data_descriptors/experiment.py +215 -0
- esgvoc/api/data_descriptors/forcing_index.py +21 -0
- esgvoc/api/data_descriptors/frequency.py +48 -0
- esgvoc/api/data_descriptors/further_info_url.py +5 -0
- esgvoc/api/data_descriptors/grid.py +43 -0
- esgvoc/api/data_descriptors/horizontal_label.py +20 -0
- esgvoc/api/data_descriptors/initialization_index.py +27 -0
- esgvoc/api/data_descriptors/institution.py +80 -0
- esgvoc/api/data_descriptors/known_branded_variable.py +75 -0
- esgvoc/api/data_descriptors/license.py +31 -0
- esgvoc/api/data_descriptors/member_id.py +9 -0
- esgvoc/api/data_descriptors/mip_era.py +26 -0
- esgvoc/api/data_descriptors/model_component.py +32 -0
- esgvoc/api/data_descriptors/models_test/models.py +17 -0
- esgvoc/api/data_descriptors/nominal_resolution.py +50 -0
- esgvoc/api/data_descriptors/obs_type.py +5 -0
- esgvoc/api/data_descriptors/organisation.py +22 -0
- esgvoc/api/data_descriptors/physics_index.py +21 -0
- esgvoc/api/data_descriptors/product.py +16 -0
- esgvoc/api/data_descriptors/publication_status.py +5 -0
- esgvoc/api/data_descriptors/realization_index.py +24 -0
- esgvoc/api/data_descriptors/realm.py +16 -0
- esgvoc/api/data_descriptors/regex.py +5 -0
- esgvoc/api/data_descriptors/region.py +35 -0
- esgvoc/api/data_descriptors/resolution.py +7 -0
- esgvoc/api/data_descriptors/source.py +120 -0
- esgvoc/api/data_descriptors/source_type.py +5 -0
- esgvoc/api/data_descriptors/sub_experiment.py +5 -0
- esgvoc/api/data_descriptors/table.py +28 -0
- esgvoc/api/data_descriptors/temporal_label.py +20 -0
- esgvoc/api/data_descriptors/time_range.py +17 -0
- esgvoc/api/data_descriptors/title.py +5 -0
- esgvoc/api/data_descriptors/tracking_id.py +67 -0
- esgvoc/api/data_descriptors/variable.py +56 -0
- esgvoc/api/data_descriptors/variant_label.py +25 -0
- esgvoc/api/data_descriptors/vertical_label.py +20 -0
- esgvoc/api/project_specs.py +143 -0
- esgvoc/api/projects.py +1253 -0
- esgvoc/api/py.typed +0 -0
- esgvoc/api/pydantic_handler.py +146 -0
- esgvoc/api/report.py +127 -0
- esgvoc/api/search.py +171 -0
- esgvoc/api/universe.py +434 -0
- esgvoc/apps/__init__.py +6 -0
- esgvoc/apps/cmor_tables/__init__.py +7 -0
- esgvoc/apps/cmor_tables/cvs_table.py +948 -0
- esgvoc/apps/drs/__init__.py +0 -0
- esgvoc/apps/drs/constants.py +2 -0
- esgvoc/apps/drs/generator.py +429 -0
- esgvoc/apps/drs/report.py +540 -0
- esgvoc/apps/drs/validator.py +312 -0
- esgvoc/apps/ga/__init__.py +104 -0
- esgvoc/apps/ga/example_usage.py +315 -0
- esgvoc/apps/ga/models/__init__.py +47 -0
- esgvoc/apps/ga/models/netcdf_header.py +306 -0
- esgvoc/apps/ga/models/validator.py +491 -0
- esgvoc/apps/ga/test_ga.py +161 -0
- esgvoc/apps/ga/validator.py +277 -0
- esgvoc/apps/jsg/json_schema_generator.py +341 -0
- esgvoc/apps/jsg/templates/template.jinja +241 -0
- esgvoc/apps/test_cv/README.md +214 -0
- esgvoc/apps/test_cv/__init__.py +0 -0
- esgvoc/apps/test_cv/cv_tester.py +1611 -0
- esgvoc/apps/test_cv/example_usage.py +216 -0
- esgvoc/apps/vr/__init__.py +12 -0
- esgvoc/apps/vr/build_variable_registry.py +71 -0
- esgvoc/apps/vr/example_usage.py +60 -0
- esgvoc/apps/vr/vr_app.py +333 -0
- esgvoc/cli/clean.py +304 -0
- esgvoc/cli/cmor.py +46 -0
- esgvoc/cli/config.py +1300 -0
- esgvoc/cli/drs.py +267 -0
- esgvoc/cli/find.py +138 -0
- esgvoc/cli/get.py +155 -0
- esgvoc/cli/install.py +41 -0
- esgvoc/cli/main.py +60 -0
- esgvoc/cli/offline.py +269 -0
- esgvoc/cli/status.py +79 -0
- esgvoc/cli/test_cv.py +258 -0
- esgvoc/cli/valid.py +147 -0
- esgvoc/core/constants.py +17 -0
- esgvoc/core/convert.py +0 -0
- esgvoc/core/data_handler.py +206 -0
- esgvoc/core/db/__init__.py +3 -0
- esgvoc/core/db/connection.py +40 -0
- esgvoc/core/db/models/mixins.py +25 -0
- esgvoc/core/db/models/project.py +102 -0
- esgvoc/core/db/models/universe.py +98 -0
- esgvoc/core/db/project_ingestion.py +231 -0
- esgvoc/core/db/universe_ingestion.py +172 -0
- esgvoc/core/exceptions.py +33 -0
- esgvoc/core/logging_handler.py +26 -0
- esgvoc/core/repo_fetcher.py +345 -0
- esgvoc/core/service/__init__.py +41 -0
- esgvoc/core/service/configuration/config_manager.py +196 -0
- esgvoc/core/service/configuration/setting.py +363 -0
- esgvoc/core/service/data_merger.py +634 -0
- esgvoc/core/service/esg_voc.py +77 -0
- esgvoc/core/service/resolver_config.py +56 -0
- esgvoc/core/service/state.py +324 -0
- esgvoc/core/service/string_heuristics.py +98 -0
- esgvoc/core/service/term_cache.py +108 -0
- esgvoc/core/service/uri_resolver.py +133 -0
- esgvoc-2.0.2.dist-info/METADATA +82 -0
- esgvoc-2.0.2.dist-info/RECORD +147 -0
- esgvoc-2.0.2.dist-info/WHEEL +4 -0
- esgvoc-2.0.2.dist-info/entry_points.txt +2 -0
- esgvoc-2.0.2.dist-info/licenses/LICENSE.txt +519 -0
esgvoc/__init__.py
ADDED
esgvoc/api/__init__.py
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
from esgvoc.api.project_specs import (
|
|
2
|
+
DrsPart,
|
|
3
|
+
DrsSpecification,
|
|
4
|
+
DrsType,
|
|
5
|
+
ProjectSpecs,
|
|
6
|
+
)
|
|
7
|
+
from esgvoc.api.projects import (
|
|
8
|
+
find_collections_in_project,
|
|
9
|
+
find_items_in_project,
|
|
10
|
+
find_terms_in_all_projects,
|
|
11
|
+
find_terms_in_collection,
|
|
12
|
+
find_terms_in_project,
|
|
13
|
+
get_all_collections_in_project,
|
|
14
|
+
get_all_projects,
|
|
15
|
+
get_all_terms_in_all_projects,
|
|
16
|
+
get_all_terms_in_collection,
|
|
17
|
+
get_all_terms_in_project,
|
|
18
|
+
get_collection_from_data_descriptor_in_all_projects,
|
|
19
|
+
get_collection_from_data_descriptor_in_project,
|
|
20
|
+
get_collection_in_project,
|
|
21
|
+
get_project,
|
|
22
|
+
get_term_in_collection,
|
|
23
|
+
get_term_in_project,
|
|
24
|
+
valid_term,
|
|
25
|
+
valid_term_in_all_projects,
|
|
26
|
+
valid_term_in_collection,
|
|
27
|
+
valid_term_in_project,
|
|
28
|
+
)
|
|
29
|
+
from esgvoc.api.report import (
|
|
30
|
+
ProjectTermError,
|
|
31
|
+
UniverseTermError,
|
|
32
|
+
ValidationError,
|
|
33
|
+
ValidationErrorVisitor,
|
|
34
|
+
ValidationReport,
|
|
35
|
+
)
|
|
36
|
+
from esgvoc.api.search import MatchingTerm
|
|
37
|
+
from esgvoc.api.universe import (
|
|
38
|
+
find_data_descriptors_in_universe,
|
|
39
|
+
find_items_in_universe,
|
|
40
|
+
find_terms_in_data_descriptor,
|
|
41
|
+
find_terms_in_universe,
|
|
42
|
+
get_all_data_descriptors_in_universe,
|
|
43
|
+
get_all_terms_in_data_descriptor,
|
|
44
|
+
get_all_terms_in_universe,
|
|
45
|
+
get_data_descriptor_in_universe,
|
|
46
|
+
get_term_in_data_descriptor,
|
|
47
|
+
get_term_in_universe,
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
__all__ = [
|
|
51
|
+
"DrsPart",
|
|
52
|
+
"DrsSpecification",
|
|
53
|
+
"DrsType",
|
|
54
|
+
"find_collections_in_project",
|
|
55
|
+
"find_data_descriptors_in_universe",
|
|
56
|
+
"find_items_in_project",
|
|
57
|
+
"find_items_in_universe",
|
|
58
|
+
"find_terms_in_all_projects",
|
|
59
|
+
"find_terms_in_collection",
|
|
60
|
+
"find_terms_in_data_descriptor",
|
|
61
|
+
"find_terms_in_project",
|
|
62
|
+
"find_terms_in_universe",
|
|
63
|
+
"get_all_collections_in_project",
|
|
64
|
+
"get_all_data_descriptors_in_universe",
|
|
65
|
+
"get_all_projects",
|
|
66
|
+
"get_all_terms_in_all_projects",
|
|
67
|
+
"get_all_terms_in_collection",
|
|
68
|
+
"get_all_terms_in_data_descriptor",
|
|
69
|
+
"get_all_terms_in_project",
|
|
70
|
+
"get_all_terms_in_universe",
|
|
71
|
+
"get_collection_from_data_descriptor_in_all_projects",
|
|
72
|
+
"get_collection_from_data_descriptor_in_project",
|
|
73
|
+
"get_collection_in_project",
|
|
74
|
+
"get_data_descriptor_in_universe",
|
|
75
|
+
"get_project",
|
|
76
|
+
"get_term_in_collection",
|
|
77
|
+
"get_term_in_data_descriptor",
|
|
78
|
+
"get_term_in_project",
|
|
79
|
+
"get_term_in_universe",
|
|
80
|
+
"MatchingTerm",
|
|
81
|
+
"ProjectSpecs",
|
|
82
|
+
"ProjectTermError",
|
|
83
|
+
"UniverseTermError",
|
|
84
|
+
"valid_term",
|
|
85
|
+
"valid_term_in_all_projects",
|
|
86
|
+
"valid_term_in_collection",
|
|
87
|
+
"valid_term_in_project",
|
|
88
|
+
"ValidationError",
|
|
89
|
+
"ValidationErrorVisitor",
|
|
90
|
+
"ValidationReport"
|
|
91
|
+
]
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"""
|
|
2
|
+
EMD (Essential Model Documentation) Pydantic Models - Version 1.0
|
|
3
|
+
|
|
4
|
+
This package implements the EMD v1.0 specification.
|
|
5
|
+
For specification details, see: Essential Model Documentation (EMD) - version 1.0.docx
|
|
6
|
+
|
|
7
|
+
Major changes from v0.993:
|
|
8
|
+
- Horizontal grid changed from flat to nested 3-level structure
|
|
9
|
+
(HorizontalComputationalGrid → HorizontalSubgrid → HorizontalGridCells)
|
|
10
|
+
- Field renames: coordinate → vertical_coordinate, native_*_grid → *_computational_grid
|
|
11
|
+
- New required description fields in Model, ModelComponent, and grids
|
|
12
|
+
- New spatial_refinement field in HorizontalGridCells
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
# Core EMD models
|
|
16
|
+
from .model import Model
|
|
17
|
+
from .model_component import EMDModelComponent
|
|
18
|
+
from .reference import Reference
|
|
19
|
+
|
|
20
|
+
# Grid models (v1.0 nested structure)
|
|
21
|
+
from .horizontal_computational_grid import HorizontalComputationalGrid
|
|
22
|
+
from .horizontal_grid_cells import HorizontalGridCells
|
|
23
|
+
from .horizontal_subgrid import HorizontalSubgrid
|
|
24
|
+
from .vertical_computational_grid import VerticalComputationalGrid
|
|
25
|
+
from .vertical_units import VerticalUnits
|
|
26
|
+
|
|
27
|
+
# Supporting models
|
|
28
|
+
from .resolution import EMDResolution
|
|
29
|
+
|
|
30
|
+
# Controlled Vocabulary (CV) models - EMD Section 7
|
|
31
|
+
from .arrangement import Arrangement
|
|
32
|
+
from .calendar import Calendar
|
|
33
|
+
from .cell_variable_type import CellVariableType
|
|
34
|
+
from .component_type import ComponentType
|
|
35
|
+
from .coordinate import Coordinate
|
|
36
|
+
from .grid_mapping import GridMapping
|
|
37
|
+
from .grid_region import GridRegion
|
|
38
|
+
from .grid_type import GridType
|
|
39
|
+
from .temporal_refinement import TemporalRefinement
|
|
40
|
+
from .truncation_method import TruncationMethod
|
|
41
|
+
|
|
42
|
+
__all__ = [
|
|
43
|
+
# Core models
|
|
44
|
+
"Model",
|
|
45
|
+
"EMDModelComponent",
|
|
46
|
+
"Reference",
|
|
47
|
+
# Grid models
|
|
48
|
+
"HorizontalComputationalGrid",
|
|
49
|
+
"HorizontalSubgrid",
|
|
50
|
+
"HorizontalGridCells",
|
|
51
|
+
"VerticalComputationalGrid",
|
|
52
|
+
"VerticalUnits",
|
|
53
|
+
# Supporting
|
|
54
|
+
"EMDResolution",
|
|
55
|
+
# CV models (Section 7)
|
|
56
|
+
"Arrangement",
|
|
57
|
+
"Calendar",
|
|
58
|
+
"CellVariableType",
|
|
59
|
+
"ComponentType",
|
|
60
|
+
"Coordinate",
|
|
61
|
+
"GridMapping",
|
|
62
|
+
"GridRegion",
|
|
63
|
+
"GridType",
|
|
64
|
+
"TemporalRefinement",
|
|
65
|
+
"TruncationMethod",
|
|
66
|
+
]
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""
|
|
2
|
+
EMD v1.0 Section 7.3 - arrangement CV
|
|
3
|
+
|
|
4
|
+
Horizontal grid arrangement types (Arakawa grids).
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from esgvoc.api.data_descriptors.data_descriptor import PlainTermDataDescriptor
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Arrangement(PlainTermDataDescriptor):
|
|
11
|
+
"""
|
|
12
|
+
Horizontal grid arrangement (EMD v1.0 Section 7.3).
|
|
13
|
+
|
|
14
|
+
Options: arakawa_a, arakawa_b, arakawa_c, arakawa_d, arakawa_e
|
|
15
|
+
|
|
16
|
+
A grid arrangement describes the relative locations of mass- and velocity-related quantities
|
|
17
|
+
on the computed grid (for instance Collins et al. (2013), and for unstructured grids
|
|
18
|
+
Thuburn et al. (2009)).
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
pass
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""
|
|
2
|
+
EMD v1.0 Section 7.4 - cell_variable_type CV
|
|
3
|
+
|
|
4
|
+
Types of physical variables carried at grid cells.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from esgvoc.api.data_descriptors.data_descriptor import PlainTermDataDescriptor
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class CellVariableType(PlainTermDataDescriptor):
|
|
11
|
+
"""
|
|
12
|
+
Cell variable type (EMD v1.0 Section 7.4).
|
|
13
|
+
|
|
14
|
+
Options: mass, x_velocity, y_velocity, velocity
|
|
15
|
+
|
|
16
|
+
Types of physical variables that are carried at, or representative of conditions at,
|
|
17
|
+
cells of a horizontal subgrid.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
pass
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from esgvoc.api.data_descriptors.data_descriptor import PlainTermDataDescriptor
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Coordinate(PlainTermDataDescriptor):
|
|
5
|
+
"""
|
|
6
|
+
Native vertical grid coordinate type. The coordinate types are all CF standard names (except where indicated) with the same definitions. See section 5.2 Native vertical grid properties.
|
|
7
|
+
Options for the native vertical grid Coordinate property:
|
|
8
|
+
• none
|
|
9
|
+
◦ (Not a standard name) There is no vertical dimension.
|
|
10
|
+
• height
|
|
11
|
+
◦ Height is the vertical distance above the earth's surface.
|
|
12
|
+
• geopotential_height
|
|
13
|
+
◦ Geopotential height is the geopotential divided by the standard acceleration due to gravity.
|
|
14
|
+
• air_pressure
|
|
15
|
+
◦ Air pressure is the pressure that exists in the medium of air.
|
|
16
|
+
• air_potential_temperature
|
|
17
|
+
◦ Air potential temperature is the temperature a parcel of air would have if moved dry adiabatically to a standard pressure.
|
|
18
|
+
• atmosphere_ln_pressure_coordinate
|
|
19
|
+
◦ Parametric atmosphere natural log pressure coordinate.
|
|
20
|
+
• atmosphere_sigma_coordinate
|
|
21
|
+
◦ Parametric atmosphere sigma coordinate.
|
|
22
|
+
• atmosphere_hybrid_sigma_pressure_coordinate
|
|
23
|
+
◦ Parametric atmosphere hybrid sigma pressure coordinate.
|
|
24
|
+
• atmosphere_hybrid_height_coordinate
|
|
25
|
+
◦ Parametric atmosphere hybrid height coordinate.
|
|
26
|
+
• atmosphere_sleve_coordinate
|
|
27
|
+
◦ Parametric atmosphere smooth vertical level coordinate.
|
|
28
|
+
• depth
|
|
29
|
+
◦ Depth is the vertical distance below the earth's surface.
|
|
30
|
+
• sea_water_pressure
|
|
31
|
+
◦ Sea water pressure is the pressure that exists in the medium of sea water.
|
|
32
|
+
• sea_water_potential_temperature
|
|
33
|
+
◦ Sea water potential temperature is the temperature a parcel of sea water would have if moved adiabatically to sea level pressure.
|
|
34
|
+
• ocean_sigma_coordinate
|
|
35
|
+
◦ Parametric ocean sigma coordinate.
|
|
36
|
+
• ocean_s_coordinate
|
|
37
|
+
◦ Parametric ocean s-coordinate.
|
|
38
|
+
• ocean_s_coordinate_g1
|
|
39
|
+
◦ Parametric ocean s-coordinate, generic form 1.
|
|
40
|
+
• ocean_s_coordinate_g2
|
|
41
|
+
◦ Parametric ocean s-coordinate, generic form 2.
|
|
42
|
+
• ocean_sigma_z_coordinate
|
|
43
|
+
◦ Parametric ocean sigma over z coordinate.
|
|
44
|
+
• ocean_double_sigma_coordinate
|
|
45
|
+
◦ Parametric ocean double sigma coordinate.
|
|
46
|
+
• land_ice_sigma_coordinate
|
|
47
|
+
◦ Land ice (glaciers, ice-caps and ice-sheets resting on bedrock and also includes ice-shelves) sigma coordinate.
|
|
48
|
+
• z*
|
|
49
|
+
◦ (Not a standard name) The z* coordinate of Adcroft and Campin (2004).
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
pass
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""
|
|
2
|
+
EMD v1.0 Section 7.7 - grid_mapping CV
|
|
3
|
+
|
|
4
|
+
Grid mapping (coordinate reference system) types.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from esgvoc.api.data_descriptors.data_descriptor import PlainTermDataDescriptor
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class GridMapping(PlainTermDataDescriptor):
|
|
11
|
+
"""
|
|
12
|
+
Grid mapping (EMD v1.0 Section 7.7).
|
|
13
|
+
|
|
14
|
+
Options: latitude_longitude, lambert_conformal_conic, etc.
|
|
15
|
+
|
|
16
|
+
The name of the coordinate reference system of the horizontal coordinates.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
pass
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""
|
|
2
|
+
EMD v1.0 Section 7.5 - region CV
|
|
3
|
+
|
|
4
|
+
Horizontal grid region types.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from esgvoc.api.data_descriptors.data_descriptor import PlainTermDataDescriptor
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class GridRegion(PlainTermDataDescriptor):
|
|
11
|
+
"""
|
|
12
|
+
Horizontal grid region (EMD v1.0 Section 7.5).
|
|
13
|
+
|
|
14
|
+
Options: global, antarctica, greenland, limited_area, 30S-90S, etc.
|
|
15
|
+
|
|
16
|
+
A region is a contiguous part of the Earth's surface which spans the horizontal grid cells.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
pass
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""
|
|
2
|
+
EMD v1.0 Section 7.6 - grid_type CV
|
|
3
|
+
|
|
4
|
+
Horizontal grid types.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from esgvoc.api.data_descriptors.data_descriptor import PlainTermDataDescriptor
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class GridType(PlainTermDataDescriptor):
|
|
11
|
+
"""
|
|
12
|
+
Horizontal grid type (EMD v1.0 Section 7.6).
|
|
13
|
+
|
|
14
|
+
Options: regular_latitude_longitude, regular_gaussian, reduced_gaussian, tripolar, etc.
|
|
15
|
+
|
|
16
|
+
A grid type describes the method for distributing grid points over the sphere.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
pass
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Horizontal computational grid description (EMD v1.0 Section 4.1.1).
|
|
3
|
+
|
|
4
|
+
A model component's horizontal computational grid is composed of one or more
|
|
5
|
+
horizontal subgrids, on which different sets of variables are calculated.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from typing import List
|
|
11
|
+
|
|
12
|
+
from pydantic import Field, field_validator
|
|
13
|
+
|
|
14
|
+
from esgvoc.api.data_descriptors.data_descriptor import DataDescriptor
|
|
15
|
+
|
|
16
|
+
from .arrangement import Arrangement
|
|
17
|
+
from .horizontal_subgrid import HorizontalSubgrid
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class HorizontalComputationalGrid(DataDescriptor):
|
|
21
|
+
"""
|
|
22
|
+
Horizontal computational grid description (EMD v1.0 Section 4.1.1).
|
|
23
|
+
|
|
24
|
+
A model component's horizontal computational grid is composed of one or more
|
|
25
|
+
horizontal subgrids, on which different sets of variables are calculated.
|
|
26
|
+
When the computational grid relies on more than one subgrid, it is referred to
|
|
27
|
+
as a "staggered" grid. For most staggered grids, the velocity-related variables
|
|
28
|
+
are calculated on a subgrid offset from the mass-related variables (e.g. pressure,
|
|
29
|
+
temperature, water vapour and other mass constituents).
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
arrangement: str | Arrangement = Field(
|
|
33
|
+
description="A characterisation of the grid staggering defining the relative positions of computed "
|
|
34
|
+
"mass-related and velocity-related variables. Taken from 7.3 arrangement CV. "
|
|
35
|
+
"Options: 'arakawa_a', 'arakawa_b', 'arakawa_c', 'arakawa_d', 'arakawa_e'. "
|
|
36
|
+
"E.g. 'arakawa_c'"
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
horizontal_subgrids: List[HorizontalSubgrid] = Field(
|
|
40
|
+
description="All of the subgrids, of which there must be at least one, used to construct the "
|
|
41
|
+
"horizontal computational grid. Each subgrid is associated with one or more variable types "
|
|
42
|
+
"(mass-related, velocity-related, etc.), consistent with the arrangement property.",
|
|
43
|
+
min_length=1,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
@field_validator("horizontal_subgrids")
|
|
47
|
+
@classmethod
|
|
48
|
+
def validate_at_least_one_subgrid(cls, v):
|
|
49
|
+
"""Validate that there is at least one horizontal subgrid."""
|
|
50
|
+
if not v or len(v) < 1:
|
|
51
|
+
raise ValueError("At least one horizontal subgrid must be provided")
|
|
52
|
+
return v
|
|
53
|
+
|
|
54
|
+
def accept(self, visitor):
|
|
55
|
+
"""Accept a data descriptor visitor."""
|
|
56
|
+
return visitor.visit_plain_term(self)
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Horizontal grid cells description (EMD v1.0 Section 4.1.3).
|
|
3
|
+
|
|
4
|
+
Horizontal grid cells are described by a coordinate system, cell resolutions,
|
|
5
|
+
as well as a number of other grid features.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import textwrap
|
|
11
|
+
from typing import Optional
|
|
12
|
+
|
|
13
|
+
from pydantic import BaseModel, Field, field_validator
|
|
14
|
+
|
|
15
|
+
from esgvoc.api.data_descriptors.data_descriptor import PlainTermDataDescriptor
|
|
16
|
+
from esgvoc.api.data_descriptors.region import Region
|
|
17
|
+
|
|
18
|
+
from .grid_mapping import GridMapping
|
|
19
|
+
from .grid_type import GridType
|
|
20
|
+
from .temporal_refinement import TemporalRefinement
|
|
21
|
+
from .truncation_method import TruncationMethod
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class HorizontalGridCells(PlainTermDataDescriptor):
|
|
25
|
+
"""
|
|
26
|
+
Horizontal grid cells description (EMD v1.0 Section 4.1.3).
|
|
27
|
+
|
|
28
|
+
Horizontal grid cells are described by a coordinate system, cell resolutions,
|
|
29
|
+
as well as a number of other grid features. The description does not include
|
|
30
|
+
any information on whether or not the grid cells form part of a model component's
|
|
31
|
+
computational grid, and so may be used to describe an arbitrary output grid.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
region: Region | str = Field(
|
|
35
|
+
description="The geographical region, or regions, over which the component is simulated. "
|
|
36
|
+
"A region is a contiguous part of the Earth's surface, and may include areas for which "
|
|
37
|
+
"no calculations are made (such as ocean areas for a land surface component). "
|
|
38
|
+
"Taken from 7.5 region CV. E.g. 'global', 'antarctica', 'greenland', 'limited_area'"
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
grid_type: str | GridType = Field(
|
|
42
|
+
description="The horizontal grid type, i.e. the method of distributing grid cells over the region. "
|
|
43
|
+
"Taken from 7.6 grid_type CV. E.g. 'regular_latitude_longitude', 'tripolar'"
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
description: Optional[str] = Field(
|
|
47
|
+
default=None,
|
|
48
|
+
description="A description of the grid. A description is only required if there is information "
|
|
49
|
+
"that is not covered by any of the other properties. Omit when not required.",
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
grid_mapping: Optional[str | GridMapping] = Field(
|
|
53
|
+
default=None,
|
|
54
|
+
description="The name of the coordinate reference system of the horizontal coordinates. "
|
|
55
|
+
"Taken from 7.7 grid_mapping CV. E.g. 'latitude_longitude', 'lambert_conformal_conic'. "
|
|
56
|
+
"Can be None or empty for certain grid types (e.g., tripolar grids).",
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
temporal_refinement: str | TemporalRefinement = Field(
|
|
60
|
+
description="The grid temporal refinement, indicating how the distribution of grid cells varies with time. "
|
|
61
|
+
"Taken from 7.8 temporal_refinement CV. E.g. 'static'"
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
spatial_refinement: Optional[str] = Field(
|
|
65
|
+
default=None,
|
|
66
|
+
description="The grid spatial refinement, indicating how the distribution of grid cells varies with space. "
|
|
67
|
+
"NEW in EMD v1.0. Omit when not applicable.",
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
x_resolution: Optional[float] = Field(
|
|
71
|
+
default=None,
|
|
72
|
+
description=textwrap.dedent(
|
|
73
|
+
"""
|
|
74
|
+
The size of grid cells in the X direction.
|
|
75
|
+
|
|
76
|
+
Cells for which no calculations are made are included (such as ocean areas
|
|
77
|
+
for a land surface component).
|
|
78
|
+
|
|
79
|
+
The X direction for a grid defined by spherical polar coordinates is longitude.
|
|
80
|
+
|
|
81
|
+
The value's physical units are given by the horizontal_units property.
|
|
82
|
+
|
|
83
|
+
Report only when cell sizes are identical or else reasonably uniform (in their given units).
|
|
84
|
+
When cells sizes in the X direction are not identical, a representative value should be
|
|
85
|
+
provided and this fact noted in the description property.
|
|
86
|
+
If the cell sizes vary by more than 25%, set this to None.
|
|
87
|
+
"""
|
|
88
|
+
),
|
|
89
|
+
gt=0,
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
y_resolution: Optional[float] = Field(
|
|
93
|
+
default=None,
|
|
94
|
+
description=textwrap.dedent(
|
|
95
|
+
"""
|
|
96
|
+
The size of grid cells in the Y direction.
|
|
97
|
+
|
|
98
|
+
Cells for which no calculations are made are included (such as ocean areas
|
|
99
|
+
for a land surface component).
|
|
100
|
+
|
|
101
|
+
The Y direction for a grid defined by spherical polar coordinates is latitude.
|
|
102
|
+
|
|
103
|
+
The value's physical units are given by the horizontal_units property.
|
|
104
|
+
|
|
105
|
+
Report only when cell sizes are identical or else reasonably uniform (in their given units).
|
|
106
|
+
When cells sizes in the Y direction are not identical, a representative value should be
|
|
107
|
+
provided and this fact noted in the description property.
|
|
108
|
+
If the cell sizes vary by more than 25%, set this to None.
|
|
109
|
+
"""
|
|
110
|
+
),
|
|
111
|
+
gt=0,
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
horizontal_units: Optional[str] = Field(
|
|
115
|
+
default=None,
|
|
116
|
+
description=textwrap.dedent(
|
|
117
|
+
"""
|
|
118
|
+
The physical units of the x_resolution and y_resolution property values.
|
|
119
|
+
|
|
120
|
+
If x_resolution and y_resolution are None, set this to None.
|
|
121
|
+
"""
|
|
122
|
+
),
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
southernmost_latitude: Optional[float] = Field(
|
|
126
|
+
default=None,
|
|
127
|
+
description=textwrap.dedent(
|
|
128
|
+
"""
|
|
129
|
+
The southernmost grid cell latitude, in degrees north.
|
|
130
|
+
|
|
131
|
+
Cells for which no calculations are made are included.
|
|
132
|
+
The southernmost latitude may be shared by multiple cells.
|
|
133
|
+
|
|
134
|
+
If the southernmost latitude is not known (e.g. the grid is adaptive), use None.
|
|
135
|
+
"""
|
|
136
|
+
),
|
|
137
|
+
ge=-90.0,
|
|
138
|
+
le=90.0,
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
westernmost_longitude: Optional[float] = Field(
|
|
142
|
+
default=None,
|
|
143
|
+
description=textwrap.dedent(
|
|
144
|
+
"""
|
|
145
|
+
The westernmost grid cell longitude, in degrees east, of the southernmost grid cell(s).
|
|
146
|
+
|
|
147
|
+
Cells for which no calculations are made are included.
|
|
148
|
+
The westernmost longitude is the smallest longitude value of the cells
|
|
149
|
+
that share the latitude given by the southernmost_latitude.
|
|
150
|
+
|
|
151
|
+
If the westernmost longitude is not known (e.g. the grid is adaptive), use None.
|
|
152
|
+
"""
|
|
153
|
+
),
|
|
154
|
+
ge=0.0,
|
|
155
|
+
le=360.0,
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
n_cells: Optional[int] = Field(
|
|
159
|
+
default=None,
|
|
160
|
+
description=textwrap.dedent(
|
|
161
|
+
"""
|
|
162
|
+
The total number of cells in the horizontal grid.
|
|
163
|
+
|
|
164
|
+
If the total number of grid cells is not constant, set to None.
|
|
165
|
+
"""
|
|
166
|
+
),
|
|
167
|
+
ge=1,
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
truncation_method: Optional[str | TruncationMethod] = Field(
|
|
171
|
+
default=None,
|
|
172
|
+
description="The method for truncating the spherical harmonic representation of a spectral model "
|
|
173
|
+
"when reporting on this grid. If the grid is not used for reporting spherical harmonic "
|
|
174
|
+
"representations, set to None.",
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
truncation_number: Optional[int] = Field(
|
|
178
|
+
default=None,
|
|
179
|
+
description="The zonal (east-west) wave number at which a spectral model is truncated when "
|
|
180
|
+
"reporting on this grid. If the grid is not used for reporting spectral models, set to None.",
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
resolution_range_km: Optional[list[float]] = Field(
|
|
184
|
+
default=None,
|
|
185
|
+
description=textwrap.dedent(
|
|
186
|
+
"""
|
|
187
|
+
The minimum and maximum resolution (in km) of cells of the horizontal grid.
|
|
188
|
+
|
|
189
|
+
Should be calculated according to the algorithm implemented by
|
|
190
|
+
https://github.com/PCMDI/nominal_resolution/blob/master/lib/api.py
|
|
191
|
+
You need to take the min and max of the array that is returned
|
|
192
|
+
when using the returnMaxDistance of the mean_resolution function.
|
|
193
|
+
"""
|
|
194
|
+
),
|
|
195
|
+
min_length=2,
|
|
196
|
+
max_length=2,
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
@field_validator("horizontal_units", mode="after")
|
|
200
|
+
@classmethod
|
|
201
|
+
def validate_horizontal_units(cls, v, info):
|
|
202
|
+
"""Validate horizontal_units."""
|
|
203
|
+
resolution_fields = {"x_resolution", "y_resolution"}
|
|
204
|
+
has_resolution = any(info.data.get(field) is not None for field in resolution_fields)
|
|
205
|
+
if has_resolution:
|
|
206
|
+
if not v:
|
|
207
|
+
raise ValueError("horizontal_units is required when x_resolution or y_resolution are set")
|
|
208
|
+
|
|
209
|
+
allowed_values = {"km", "degree"}
|
|
210
|
+
if v not in allowed_values:
|
|
211
|
+
msg = f"horizontal_units must be one of {allowed_values}. Received: {v}"
|
|
212
|
+
raise ValueError(msg)
|
|
213
|
+
elif v:
|
|
214
|
+
msg = f"If all of {resolution_fields} are None, then horizontal_units must also be None. Received: {v}"
|
|
215
|
+
raise ValueError(msg)
|
|
216
|
+
|
|
217
|
+
return v
|
|
218
|
+
|
|
219
|
+
@field_validator("resolution_range_km")
|
|
220
|
+
@classmethod
|
|
221
|
+
def validate_resolution_range(cls, v):
|
|
222
|
+
"""Validate that resolution range has exactly 2 values and min <= max."""
|
|
223
|
+
if v is not None:
|
|
224
|
+
if len(v) != 2:
|
|
225
|
+
raise ValueError("resolution_range_km must contain exactly 2 values [min, max]")
|
|
226
|
+
if v[0] > v[1]:
|
|
227
|
+
raise ValueError("resolution_range_km: minimum must be <= maximum")
|
|
228
|
+
if any(val <= 0 for val in v):
|
|
229
|
+
raise ValueError("resolution_range_km values must be > 0")
|
|
230
|
+
return v
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Horizontal subgrid description (EMD v1.0 Section 4.1.2).
|
|
3
|
+
|
|
4
|
+
A horizontal subgrid describes the grid cells at one of the stagger positions
|
|
5
|
+
of a horizontal computational grid.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from typing import List
|
|
11
|
+
|
|
12
|
+
from pydantic import BaseModel, Field
|
|
13
|
+
|
|
14
|
+
from esgvoc.api.data_descriptors.data_descriptor import PlainTermDataDescriptor
|
|
15
|
+
|
|
16
|
+
from .cell_variable_type import CellVariableType
|
|
17
|
+
from .horizontal_grid_cells import HorizontalGridCells
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class HorizontalSubgrid(PlainTermDataDescriptor):
|
|
21
|
+
"""
|
|
22
|
+
Horizontal subgrid description (EMD v1.0 Section 4.1.2).
|
|
23
|
+
|
|
24
|
+
A horizontal subgrid describes the grid cells at one of the stagger positions
|
|
25
|
+
of a horizontal computational grid. Often the locations of mass-related and
|
|
26
|
+
velocity-related variables differ, so more than one horizontal subgrid will
|
|
27
|
+
be defined as part of a horizontal computational grid.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
cell_variable_type: List[str | CellVariableType] = Field(
|
|
31
|
+
description="The types of physical variables that are carried at, or representative of conditions at, "
|
|
32
|
+
"the cells described by this horizontal subgrid. Taken from 7.4 cell_variable_type CV. "
|
|
33
|
+
"Options: 'mass', 'x_velocity', 'y_velocity', 'velocity'. "
|
|
34
|
+
"E.g. ['mass'], ['x_velocity'], ['mass', 'x_velocity', 'y_velocity'], ['mass', 'velocity']. "
|
|
35
|
+
"Can be an empty list in certain cases.",
|
|
36
|
+
default_factory=list,
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
horizontal_grid_cells: HorizontalGridCells = Field(
|
|
40
|
+
description="A description of the characteristics and location of the grid cells of this subgrid."
|
|
41
|
+
)
|