climate-ref 0.6.5__py3-none-any.whl → 0.7.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 (40) hide show
  1. climate_ref/cli/__init__.py +12 -3
  2. climate_ref/cli/_utils.py +56 -2
  3. climate_ref/cli/datasets.py +48 -9
  4. climate_ref/cli/executions.py +351 -24
  5. climate_ref/cli/providers.py +1 -2
  6. climate_ref/config.py +4 -4
  7. climate_ref/database.py +62 -4
  8. climate_ref/dataset_registry/obs4ref_reference.txt +0 -9
  9. climate_ref/dataset_registry/sample_data.txt +269 -107
  10. climate_ref/datasets/__init__.py +3 -3
  11. climate_ref/datasets/base.py +121 -20
  12. climate_ref/datasets/cmip6.py +2 -0
  13. climate_ref/datasets/obs4mips.py +26 -15
  14. climate_ref/executor/__init__.py +8 -1
  15. climate_ref/executor/hpc.py +7 -1
  16. climate_ref/executor/result_handling.py +151 -64
  17. climate_ref/migrations/env.py +12 -10
  18. climate_ref/migrations/versions/2025-07-20T1521_94beace57a9c_cmip6_finalised.py +1 -1
  19. climate_ref/migrations/versions/2025-08-05T0327_a1b2c3d4e5f6_finalised_on_base_dataset.py +1 -1
  20. climate_ref/migrations/versions/2025-09-05T2019_8d28e5e0f9c3_add_indexes.py +108 -0
  21. climate_ref/migrations/versions/2025-09-10T1358_2f6e36738e06_use_version_as_version_facet_for_.py +35 -0
  22. climate_ref/migrations/versions/2025-09-22T2359_20cd136a5b04_add_pmp_version.py +35 -0
  23. climate_ref/models/__init__.py +1 -6
  24. climate_ref/models/base.py +4 -18
  25. climate_ref/models/dataset.py +10 -6
  26. climate_ref/models/diagnostic.py +2 -1
  27. climate_ref/models/execution.py +225 -12
  28. climate_ref/models/metric_value.py +27 -112
  29. climate_ref/models/mixins.py +144 -0
  30. climate_ref/models/provider.py +2 -1
  31. climate_ref/provider_registry.py +4 -4
  32. climate_ref/slurm.py +2 -2
  33. climate_ref/testing.py +1 -1
  34. {climate_ref-0.6.5.dist-info → climate_ref-0.7.0.dist-info}/METADATA +2 -2
  35. climate_ref-0.7.0.dist-info/RECORD +58 -0
  36. climate_ref-0.6.5.dist-info/RECORD +0 -54
  37. {climate_ref-0.6.5.dist-info → climate_ref-0.7.0.dist-info}/WHEEL +0 -0
  38. {climate_ref-0.6.5.dist-info → climate_ref-0.7.0.dist-info}/entry_points.txt +0 -0
  39. {climate_ref-0.6.5.dist-info → climate_ref-0.7.0.dist-info}/licenses/LICENCE +0 -0
  40. {climate_ref-0.6.5.dist-info → climate_ref-0.7.0.dist-info}/licenses/NOTICE +0 -0
@@ -2,12 +2,11 @@ import enum
2
2
  from collections.abc import Mapping
3
3
  from typing import TYPE_CHECKING, Any, ClassVar
4
4
 
5
- from loguru import logger
6
- from sqlalchemy import Column, ForeignKey, Text, event
5
+ from sqlalchemy import ForeignKey, event
7
6
  from sqlalchemy.orm import Mapped, mapped_column, relationship
8
7
 
9
- from climate_ref.models.base import Base, CreatedUpdatedMixin
10
- from climate_ref_core.pycmec.controlled_vocabulary import CV, Dimension
8
+ from climate_ref.models.base import Base
9
+ from climate_ref.models.mixins import CreatedUpdatedMixin, DimensionMixin
11
10
 
12
11
  if TYPE_CHECKING:
13
12
  from climate_ref.models.execution import Execution
@@ -27,11 +26,14 @@ class MetricValueType(enum.Enum):
27
26
  SERIES = "series"
28
27
 
29
28
 
30
- class MetricValue(CreatedUpdatedMixin, Base):
29
+ class MetricValue(DimensionMixin, CreatedUpdatedMixin, Base):
31
30
  """
32
31
  Represents a single metric value
33
32
 
34
- This value has a number of dimensions which are used to query the diagnostic value.
33
+ This is a base class for different types of metric values (e.g. scalar, series) which
34
+ are stored in a single table using single table inheritance.
35
+
36
+ This value has a number of dimensions which are used to query the diagnostic values.
35
37
  These dimensions describe aspects such as the type of statistic being measured,
36
38
  the region of interest or the model from which the statistic is being measured.
37
39
 
@@ -46,125 +48,25 @@ class MetricValue(CreatedUpdatedMixin, Base):
46
48
  "polymorphic_on": "type",
47
49
  }
48
50
 
51
+ _cv_dimensions: ClassVar[list[str]] = []
52
+
49
53
  id: Mapped[int] = mapped_column(primary_key=True)
50
- execution_id: Mapped[int] = mapped_column(ForeignKey("execution.id"))
54
+ execution_id: Mapped[int] = mapped_column(ForeignKey("execution.id"), index=True)
51
55
 
52
56
  attributes: Mapped[dict[str, Any]] = mapped_column()
53
57
 
54
58
  execution: Mapped["Execution"] = relationship(back_populates="values")
55
59
 
56
- type: Mapped[MetricValueType] = mapped_column()
60
+ type: Mapped[MetricValueType] = mapped_column(index=True)
57
61
  """
58
62
  Type of metric value
59
63
 
60
64
  This value is used to determine how the metric value should be interpreted.
61
65
  """
62
66
 
63
- _cv_dimensions: ClassVar[list[str]] = []
64
-
65
- @property
66
- def dimensions(self) -> dict[str, str]:
67
- """
68
- Get the non-null dimensions and their values
69
-
70
- Any changes to the resulting dictionary are not reflected in the object
71
-
72
- Returns
73
- -------
74
- Collection of dimensions names and their values
75
- """
76
- dims = {}
77
- for key in self._cv_dimensions:
78
- value = getattr(self, key)
79
- if value is not None:
80
- dims[key] = value
81
- return dims
82
-
83
67
  def __repr__(self) -> str:
84
68
  return f"<MetricValue id={self.id} execution={self.execution} dimensions={self.dimensions}>"
85
69
 
86
- @staticmethod
87
- def build_dimension_column(dimension: Dimension) -> Column[str]:
88
- """
89
- Create a column representing a CV dimension
90
-
91
- These columns are not automatically generated with alembic revisions.
92
- Any changes to this functionality likely require a manual database migration
93
- of the existing columns.
94
-
95
- Parameters
96
- ----------
97
- dimension
98
- Dimension definition to create the column for.
99
-
100
- Currently only the "name" field is being used.
101
-
102
- Returns
103
- -------
104
- An instance of a sqlalchemy Column
105
-
106
- This doesn't create the column in the database,
107
- but enables the ORM to access it.
108
-
109
- """
110
- return Column(
111
- dimension.name,
112
- Text,
113
- index=True,
114
- nullable=True,
115
- info={"skip_autogenerate": True},
116
- )
117
-
118
- @classmethod
119
- def register_cv_dimensions(cls, cv: CV) -> None:
120
- """
121
- Register the dimensions supplied in the controlled vocabulary
122
-
123
- This has to be done at run-time to support custom CVs.
124
- Any extra columns already in the database, but not in the CV are ignored.
125
-
126
- Parameters
127
- ----------
128
- cv
129
- Controlled vocabulary being used by the application.
130
- This controlled vocabulary contains the definitions of the dimensions that can be used.
131
- """
132
- for dimension in cv.dimensions:
133
- target_attribute = dimension.name
134
- if target_attribute in cls._cv_dimensions:
135
- continue
136
-
137
- cls._cv_dimensions.append(target_attribute)
138
- logger.debug(f"Registered MetricValue dimension: {target_attribute}")
139
-
140
- if hasattr(cls, target_attribute):
141
- # This should only occur in test suite as we don't support removing dimensions at runtime
142
- logger.warning("Column attribute already exists on MetricValue. Ignoring")
143
- else:
144
- setattr(cls, target_attribute, cls.build_dimension_column(dimension))
145
-
146
- # TODO: Check if the underlying table already contains columns
147
-
148
- @classmethod
149
- def _reset_cv_dimensions(cls) -> None:
150
- """
151
- Remove any previously registered dimensions
152
-
153
- Used by the test suite and should not be called at runtime.
154
-
155
- This doesn't remove any previous column definitions due to a limitation that columns in
156
- declarative classes cannot be removed.
157
- This means that `hasattr(MetricValue, "old_attribute")`
158
- will still return True after resetting, but the values will not be included in any executions.
159
- """
160
- logger.warning(f"Removing MetricValue dimensions: {cls._cv_dimensions}")
161
-
162
- keys = list(cls._cv_dimensions)
163
- for key in keys:
164
- cls._cv_dimensions.remove(key)
165
-
166
- assert not len(cls._cv_dimensions)
167
-
168
70
 
169
71
  class ScalarMetricValue(MetricValue):
170
72
  """
@@ -180,6 +82,12 @@ class ScalarMetricValue(MetricValue):
180
82
  # This is a scalar value
181
83
  value: Mapped[float] = mapped_column(nullable=True)
182
84
 
85
+ def __repr__(self) -> str:
86
+ return (
87
+ f"<ScalarMetricValue "
88
+ f"id={self.id} execution={self.execution} dimensions={self.dimensions} value={self.value}>"
89
+ )
90
+
183
91
  @classmethod
184
92
  def build(
185
93
  cls,
@@ -232,9 +140,10 @@ class ScalarMetricValue(MetricValue):
232
140
 
233
141
  class SeriesMetricValue(MetricValue):
234
142
  """
235
- A scalar value with an associated dimensions
143
+ A 1d series with associated dimensions
236
144
 
237
- This is a subclass of MetricValue that is used to represent a scalar value.
145
+ This is a subclass of MetricValue that is used to represent a series.
146
+ This can be used to represent time series, vertical profiles or other 1d data.
238
147
  """
239
148
 
240
149
  __mapper_args__: ClassVar[Mapping[str, Any]] = { # type: ignore
@@ -246,6 +155,12 @@ class SeriesMetricValue(MetricValue):
246
155
  index: Mapped[list[float | int | str]] = mapped_column(nullable=True)
247
156
  index_name: Mapped[str] = mapped_column(nullable=True)
248
157
 
158
+ def __repr__(self) -> str:
159
+ return (
160
+ f"<SeriesMetricValue id={self.id} execution={self.execution} "
161
+ f"dimensions={self.dimensions} index_name={self.index_name}>"
162
+ )
163
+
249
164
  @classmethod
250
165
  def build( # noqa: PLR0913
251
166
  cls,
@@ -0,0 +1,144 @@
1
+ """Model mixins for shared functionality"""
2
+
3
+ import datetime
4
+ from typing import TYPE_CHECKING, ClassVar
5
+
6
+ from loguru import logger
7
+ from sqlalchemy import Column, Text, func
8
+ from sqlalchemy.orm import Mapped, mapped_column
9
+
10
+ if TYPE_CHECKING:
11
+ from climate_ref_core.pycmec.controlled_vocabulary import CV, Dimension
12
+
13
+
14
+ class CreatedUpdatedMixin:
15
+ """
16
+ Mixin for models that have a created_at and updated_at fields
17
+ """
18
+
19
+ created_at: Mapped[datetime.datetime] = mapped_column(server_default=func.now())
20
+ """
21
+ When the dataset was added to the database
22
+ """
23
+
24
+ updated_at: Mapped[datetime.datetime] = mapped_column(
25
+ server_default=func.now(), onupdate=func.now(), index=True
26
+ )
27
+ """
28
+ When the dataset was updated.
29
+ """
30
+
31
+
32
+ class DimensionMixin:
33
+ """
34
+ Mixin that adds controlled vocabulary dimension support to a model
35
+
36
+ This mixin provides methods and properties for managing CV dimensions
37
+ on database models. Dimensions are stored as individual indexed columns
38
+ that are registered at runtime based on the controlled vocabulary.
39
+
40
+ Classes using this mixin must:
41
+ - Define _cv_dimensions as a ClassVar[list[str]] = []
42
+ - Have a __tablename__ attribute (SQLAlchemy requirement)
43
+ """
44
+
45
+ _cv_dimensions: ClassVar[list[str]]
46
+
47
+ @property
48
+ def dimensions(self) -> dict[str, str]:
49
+ """
50
+ Get the non-null dimensions and their values
51
+
52
+ Any changes to the resulting dictionary are not reflected in the object
53
+
54
+ Returns
55
+ -------
56
+ Collection of dimension names and their values
57
+ """
58
+ dims = {}
59
+ for key in self._cv_dimensions:
60
+ value = getattr(self, key)
61
+ if value is not None:
62
+ dims[key] = value
63
+ return dims
64
+
65
+ @staticmethod
66
+ def build_dimension_column(dimension: "Dimension") -> Column[str]:
67
+ """
68
+ Create a column representing a CV dimension
69
+
70
+ These columns are not automatically generated with alembic revisions.
71
+ Any changes to this functionality likely require a manual database migration
72
+ of the existing columns.
73
+
74
+ Parameters
75
+ ----------
76
+ dimension
77
+ Dimension definition to create the column for.
78
+ Currently only the "name" field is being used.
79
+
80
+ Returns
81
+ -------
82
+ An instance of a sqlalchemy Column
83
+
84
+ This doesn't create the column in the database,
85
+ but enables the ORM to access it.
86
+ """
87
+ return Column(
88
+ dimension.name,
89
+ Text,
90
+ index=True,
91
+ nullable=True,
92
+ info={"skip_autogenerate": True},
93
+ )
94
+
95
+ @classmethod
96
+ def register_cv_dimensions(cls, cv: "CV") -> None:
97
+ """
98
+ Register the dimensions supplied in the controlled vocabulary
99
+
100
+ This has to be done at run-time to support custom CVs.
101
+ Any extra columns already in the database, but not in the CV are ignored.
102
+
103
+ Parameters
104
+ ----------
105
+ cv
106
+ Controlled vocabulary being used by the application.
107
+ This controlled vocabulary contains the definitions of the dimensions that can be used.
108
+ """
109
+ model_name = cls.__name__
110
+
111
+ for dimension in cv.dimensions:
112
+ target_attribute = dimension.name
113
+ if target_attribute in cls._cv_dimensions:
114
+ continue
115
+
116
+ cls._cv_dimensions.append(target_attribute)
117
+ logger.debug(f"Registered {model_name} dimension: {target_attribute}")
118
+
119
+ if hasattr(cls, target_attribute):
120
+ # This should only occur in test suite as we don't support removing dimensions at runtime
121
+ logger.warning(f"Column attribute already exists on {model_name}. Ignoring")
122
+ else:
123
+ setattr(cls, target_attribute, cls.build_dimension_column(dimension))
124
+
125
+ @classmethod
126
+ def _reset_cv_dimensions(cls) -> None:
127
+ """
128
+ Remove any previously registered dimensions
129
+
130
+ Used by the test suite and should not be called at runtime.
131
+
132
+ This doesn't remove any previous column definitions due to a limitation that columns in
133
+ declarative classes cannot be removed.
134
+ This means that `hasattr(cls, "old_attribute")`
135
+ will still return True after resetting, but the values will not be included in any executions.
136
+ """
137
+ model_name = cls.__name__
138
+ logger.warning(f"Removing {model_name} dimensions: {cls._cv_dimensions}")
139
+
140
+ keys = list(cls._cv_dimensions)
141
+ for key in keys:
142
+ cls._cv_dimensions.remove(key)
143
+
144
+ assert not len(cls._cv_dimensions)
@@ -2,7 +2,8 @@ from typing import TYPE_CHECKING
2
2
 
3
3
  from sqlalchemy.orm import Mapped, mapped_column, relationship
4
4
 
5
- from climate_ref.models.base import Base, CreatedUpdatedMixin
5
+ from .base import Base
6
+ from .mixins import CreatedUpdatedMixin
6
7
 
7
8
  if TYPE_CHECKING:
8
9
  from climate_ref.models.diagnostic import Diagnostic
@@ -14,6 +14,8 @@ from loguru import logger
14
14
 
15
15
  from climate_ref.config import Config
16
16
  from climate_ref.database import Database
17
+ from climate_ref.models import Diagnostic as DiagnosticModel
18
+ from climate_ref.models import Provider as ProviderModel
17
19
  from climate_ref_core.diagnostics import Diagnostic
18
20
  from climate_ref_core.providers import DiagnosticProvider, import_provider
19
21
 
@@ -29,10 +31,8 @@ def _register_provider(db: Database, provider: DiagnosticProvider) -> None:
29
31
  provider
30
32
  DiagnosticProvider instance
31
33
  """
32
- from climate_ref.models import Diagnostic, Provider
33
-
34
34
  provider_model, created = db.get_or_create(
35
- Provider,
35
+ ProviderModel,
36
36
  slug=provider.slug,
37
37
  defaults={
38
38
  "name": provider.name,
@@ -46,7 +46,7 @@ def _register_provider(db: Database, provider: DiagnosticProvider) -> None:
46
46
 
47
47
  for diagnostic in provider.diagnostics():
48
48
  diagnostic_model, created = db.get_or_create(
49
- Diagnostic,
49
+ DiagnosticModel,
50
50
  slug=diagnostic.slug,
51
51
  provider_id=provider_model.id,
52
52
  defaults={
climate_ref/slurm.py CHANGED
@@ -10,14 +10,14 @@ class SlurmChecker:
10
10
 
11
11
  def __init__(self, intest: bool = False) -> None:
12
12
  if HAS_REAL_SLURM:
13
- import pyslurm # type: ignore
13
+ import pyslurm # type: ignore # noqa: PLC0415
14
14
 
15
15
  self.slurm_association: dict[int, Any] | None = pyslurm.db.Associations.load()
16
16
  self.slurm_partition: dict[str, Any] | None = pyslurm.Partitions.load()
17
17
  self.slurm_qos: dict[str, Any] | None = pyslurm.qos().get()
18
18
  self.slurm_node: dict[str, Any] | None = pyslurm.Nodes.load()
19
19
  elif intest:
20
- import pyslurm
20
+ import pyslurm # noqa: PLC0415
21
21
 
22
22
  self.slurm_association = pyslurm.db.Associations.load() # dict [num -> Association]
23
23
  self.slurm_partition = pyslurm.Partitions.load() # collection
climate_ref/testing.py CHANGED
@@ -27,7 +27,7 @@ def _determine_test_directory() -> Path | None:
27
27
 
28
28
 
29
29
  TEST_DATA_DIR = _determine_test_directory()
30
- SAMPLE_DATA_VERSION = "v0.6.3"
30
+ SAMPLE_DATA_VERSION = "v0.7.4"
31
31
 
32
32
 
33
33
  def fetch_sample_data(force_cleanup: bool = False, symlink: bool = False) -> None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: climate-ref
3
- Version: 0.6.5
3
+ Version: 0.7.0
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-Expression: Apache-2.0
@@ -70,7 +70,7 @@ pip install climate-ref
70
70
  If you want to use the diagnostic providers for the Assessment Fast Track, you can install them with:
71
71
 
72
72
  ```bash
73
- pip install climate-ref[aft-providers]
73
+ pip install "climate-ref[aft-providers]"
74
74
  ```
75
75
 
76
76
  ## Quick Start
@@ -0,0 +1,58 @@
1
+ climate_ref/__init__.py,sha256=M45QGfl0KCPK48A8MjI08weNvZHMYH__GblraQMxsoM,808
2
+ climate_ref/_config_helpers.py,sha256=-atI5FX7SukhLE_jz_rL-EHQ7s0YYqKu3dSFYWxSyMU,6632
3
+ climate_ref/alembic.ini,sha256=WRvbwSIFuZ7hWNMnR2-yHPJAwYUnwhvRYBzkJhtpGdg,3535
4
+ climate_ref/config.py,sha256=RfyX59yGtOrzW1F6-fSBhpM24z54KU3O8HGC-O44vDo,17473
5
+ climate_ref/constants.py,sha256=9RaNLgUSuQva7ki4eRW3TjOKeVP6T81QNiu0veB1zVk,111
6
+ climate_ref/database.py,sha256=stO0K61D8Jh6zRXpjq8rTTeuz0aSi2ZEmeb_9ZqUHJc,10707
7
+ climate_ref/provider_registry.py,sha256=NJssVC0ws7BqaYnAPy-1jSxwdFSXl1VCId67WXMUeGU,4230
8
+ climate_ref/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ climate_ref/slurm.py,sha256=N2L1pZ1A79dtkASEFU4TUjrVg2qtYUf7HMeoGXErTyA,7338
10
+ climate_ref/solver.py,sha256=T5sQjweSvpUMG4q8MfbGjljxa5kBgKxNotT78PwyxqU,16804
11
+ climate_ref/testing.py,sha256=5zte0H4trwxOgRpzAJJ8by8aGuDSDOQAlUqFBgqjhWg,4256
12
+ climate_ref/cli/__init__.py,sha256=iVgsOBnf4YNgLwxoR-VCrrcnMWM90wtLBFxvI7AaHB0,4576
13
+ climate_ref/cli/_utils.py,sha256=KQDp-0YDLXqljpcUFUGoksloJocMWbwh3-kxoUqMbgo,3440
14
+ climate_ref/cli/config.py,sha256=ak4Rn9S6fH23PkHHlI-pXuPiZYOvUB4r26eu3p525-M,532
15
+ climate_ref/cli/datasets.py,sha256=fpRN9YeuZHrkNEjjd5JSrqFSmfO1rCYpdzzYjl5DZPI,9997
16
+ climate_ref/cli/executions.py,sha256=O1xm89r9cI4e99VzLgc5pbhrp71OjROEHa6-GRjaFg4,18191
17
+ climate_ref/cli/providers.py,sha256=8C3xSDBdzfUMil6HPG9a7g0_EKQEmlfPbI3VnN_NmMI,2590
18
+ climate_ref/cli/solve.py,sha256=ZTXrwDFDXNrX5GLMJTN9tFnpV3zlcZbEu2aF3JDJVxI,2367
19
+ climate_ref/dataset_registry/obs4ref_reference.txt,sha256=szXNhA5wx1n2XfYiXPl4FipmjE1Kp5Jrj2UuBLHqNvw,7351
20
+ climate_ref/dataset_registry/sample_data.txt,sha256=w3heh6MMbZ9Jp_SAwLcwWVkq91IRxZh3spwKz-YFRt0,43869
21
+ climate_ref/datasets/__init__.py,sha256=oC0fhdMfie7IfzBwU7BtD5Tv4bJP4zQOK3XgnMQXtSw,1222
22
+ climate_ref/datasets/base.py,sha256=M0hGMlRn1iiridnp7Kc0gckapdEjSSKZyQ1lv8USYIU,15383
23
+ climate_ref/datasets/cmip6.py,sha256=0R79QfRuqTa_wUHHkYCYf8zpJXHzJw2CXbuDKNlY3Bg,7212
24
+ climate_ref/datasets/cmip6_parsers.py,sha256=wH4WKQAR2_aniXwsW7nch6nIpXk2pSpPxkT4unjV4hQ,6041
25
+ climate_ref/datasets/obs4mips.py,sha256=AerO5QaISiRYPzBm_C6lGsKQgE_Zyzo4XoOOKrpB-TE,6586
26
+ climate_ref/datasets/pmp_climatology.py,sha256=goHDc_3B2Wdiy_hmpERNvWDdDYZACPOyFDt3Du6nGc0,534
27
+ climate_ref/datasets/utils.py,sha256=iLJO7h4G3DWsRe9hIC4qkIyi5_zIW1ZMw-FDASLujtM,359
28
+ climate_ref/executor/__init__.py,sha256=tXuXxoFQKH9-te4O3bJg9dVrBKtjRS2si0yzRsHVfGk,902
29
+ climate_ref/executor/hpc.py,sha256=DEp_Q5kDfBTPF_4mgyedjKbXtNZ-OmIkS9bbYo2B1FQ,14153
30
+ climate_ref/executor/local.py,sha256=65LUl41YtURFb87YTWZQHjDpIRlIKJ5Ny51c9DZjy0s,8582
31
+ climate_ref/executor/pbs_scheduler.py,sha256=WoH1sTmDl7bdmYodpcxZjkUSvInYUcWR4x7buIgBxqk,5807
32
+ climate_ref/executor/result_handling.py,sha256=Xm712JB3Lk-gmSOv_sKDtJdgHeJioSjSZV5cpX3OtS0,10961
33
+ climate_ref/executor/synchronous.py,sha256=o4TndsoKMu9AzJYLkusU9lRkgHCy6HcCP46tEs6o86U,1895
34
+ climate_ref/migrations/README,sha256=xM5osYbyEbEFA2eh5kwary_oh-5VFWtDubA-vgWwvlE,935
35
+ climate_ref/migrations/env.py,sha256=jSW4j__q39MaWRHBJ_FZFHl7gEZ7b6_YyU5wDxxzpWQ,4570
36
+ climate_ref/migrations/script.py.mako,sha256=MEqL-2qATlST9TAOeYgscMn1uy6HUS9NFvDgl93dMj8,635
37
+ climate_ref/migrations/versions/2025-05-02T1418_341a4aa2551e_regenerate.py,sha256=S8Q4THCI4TPnlaQHgQJUCiNW5LAyQClaiTB-0dwhtXU,14050
38
+ climate_ref/migrations/versions/2025-05-09T2032_03dbb4998e49_series_metric_value.py,sha256=s9nZ_l64pSF7sWN53rRPCQlqW_xHqR8tlWhU-ovmsME,2043
39
+ climate_ref/migrations/versions/2025-07-03T1505_795c1e6cf496_drop_unique_requirement_on_slug.py,sha256=TfBHJkm3oPlz0P5Z1tiY6LBp2B1oDvdyL_OOYoV-OiI,984
40
+ climate_ref/migrations/versions/2025-07-20T1521_94beace57a9c_cmip6_finalised.py,sha256=pzxhT9aFaEqyyUOWf0AExsr6sMW9syyr1RUhy0nj3AM,2907
41
+ climate_ref/migrations/versions/2025-08-05T0327_a1b2c3d4e5f6_finalised_on_base_dataset.py,sha256=Uen3ryUfmIpASeIQYuUJd9xDxnEl5ItTx3jKuHoDSko,2033
42
+ climate_ref/migrations/versions/2025-09-05T2019_8d28e5e0f9c3_add_indexes.py,sha256=r8xKMIykdQbnrtBgmfTtfs5uHlmiQJNp7g5IdWi4zrs,5456
43
+ climate_ref/migrations/versions/2025-09-10T1358_2f6e36738e06_use_version_as_version_facet_for_.py,sha256=s7Vf28NxgKLSIJBX2n8kdfInDbHRD034g1pA5yd5tlg,1006
44
+ climate_ref/migrations/versions/2025-09-22T2359_20cd136a5b04_add_pmp_version.py,sha256=ION7atI6vPiCpM_wvEqn7H3VPyQzmeUQWjO1GRji4oY,992
45
+ climate_ref/models/__init__.py,sha256=uvy_3LLYyyCLeh7144VaHcyt_TPB8ynbQafLRJZ9qPg,741
46
+ climate_ref/models/base.py,sha256=mDfsrw6-IiSO3MbR3f0BTJySM_j3Oty--dg3A3ugn0g,857
47
+ climate_ref/models/dataset.py,sha256=AqKsBiAXfeie8POhkW25yG8wmmPDlG4dpiN15aT3CIg,8242
48
+ climate_ref/models/diagnostic.py,sha256=f2b4HoET56B_sYRGGfrpATdUmGlngUmsf2UzL1Uzp8M,1788
49
+ climate_ref/models/execution.py,sha256=gfkrs0wyySNVQpfob1Bc-26iLDV99K6aSPHs0GZmdNY,17548
50
+ climate_ref/models/metric_value.py,sha256=NFvduNVyB5aOj8rwn8KiPDzIjomBzIroAyFACkSSEUw,7400
51
+ climate_ref/models/mixins.py,sha256=1EAJU2RlhY-9UUIN8F5SZOg5k5uD9r1rG6isvrjQF0o,4683
52
+ climate_ref/models/provider.py,sha256=OnoacwAa50XBS9CCgxJnylIfsGXFP4EqTlLhBXmh6So,991
53
+ climate_ref-0.7.0.dist-info/METADATA,sha256=sswbnom4j-Fpg12A-2XVsQx8EhkqGTQoaK7e4p08Eo8,4507
54
+ climate_ref-0.7.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
55
+ climate_ref-0.7.0.dist-info/entry_points.txt,sha256=IaggEJlDIhoYWXdXJafacWbWtCcoEqUKceP1qD7_7vU,44
56
+ climate_ref-0.7.0.dist-info/licenses/LICENCE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
57
+ climate_ref-0.7.0.dist-info/licenses/NOTICE,sha256=4qTlax9aX2-mswYJuVrLqJ9jK1IkN5kSBqfVvYLF3Ws,128
58
+ climate_ref-0.7.0.dist-info/RECORD,,
@@ -1,54 +0,0 @@
1
- climate_ref/__init__.py,sha256=M45QGfl0KCPK48A8MjI08weNvZHMYH__GblraQMxsoM,808
2
- climate_ref/_config_helpers.py,sha256=-atI5FX7SukhLE_jz_rL-EHQ7s0YYqKu3dSFYWxSyMU,6632
3
- climate_ref/alembic.ini,sha256=WRvbwSIFuZ7hWNMnR2-yHPJAwYUnwhvRYBzkJhtpGdg,3535
4
- climate_ref/config.py,sha256=WW6R7RLwEDuI11XYLYO57FwvmQz1psq9bNM3WVL3e_s,17481
5
- climate_ref/constants.py,sha256=9RaNLgUSuQva7ki4eRW3TjOKeVP6T81QNiu0veB1zVk,111
6
- climate_ref/database.py,sha256=b_6XHdr78Mo7KeLqQJ5DjLsySHPdQE83P8dRpdMfzfM,8661
7
- climate_ref/provider_registry.py,sha256=dyfj4vU6unKHNXtT03HafQtAi3LilL37uvu3paCnmNY,4159
8
- climate_ref/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- climate_ref/slurm.py,sha256=XWXVPdXP-4BDib3bxYW9uPcAJdPpo1ixYZAI_y1cZuw,7305
10
- climate_ref/solver.py,sha256=T5sQjweSvpUMG4q8MfbGjljxa5kBgKxNotT78PwyxqU,16804
11
- climate_ref/testing.py,sha256=1b9lVCJlKxjJ7JGq6zDD2gK3BEM9ZVv1dbA-j6yb4Yk,4256
12
- climate_ref/cli/__init__.py,sha256=fvENOeL4j7CMPANVxrDlWfaB0QUvvYgrWcm5ptbL0P8,4350
13
- climate_ref/cli/_utils.py,sha256=6bIb8zEVvzXyKpv8MG58T-T2L2jH-G8WNrOOGpz3uCw,1918
14
- climate_ref/cli/config.py,sha256=ak4Rn9S6fH23PkHHlI-pXuPiZYOvUB4r26eu3p525-M,532
15
- climate_ref/cli/datasets.py,sha256=4iYQZ0ceoF-Cd8eSpS4Q8b9aLt_vEDUw5slzGw02DsY,8277
16
- climate_ref/cli/executions.py,sha256=2MjwxCdRB-uVJUg7RluDIf_IsoclRn22ibJjk_nhfPo,7215
17
- climate_ref/cli/providers.py,sha256=-5hQkJc01jON1bc1dk--tSWTesyiHOzZuYMb9Vxge9k,2613
18
- climate_ref/cli/solve.py,sha256=ZTXrwDFDXNrX5GLMJTN9tFnpV3zlcZbEu2aF3JDJVxI,2367
19
- climate_ref/dataset_registry/obs4ref_reference.txt,sha256=2zJMbsAsQ49KaWziX3CqrlILq9yN7S2ygmfV3V5rsnw,8395
20
- climate_ref/dataset_registry/sample_data.txt,sha256=3JAHy14pRbLlo9-oNxUXLgZ_QOFJXUieEftBbapSY8E,20124
21
- climate_ref/datasets/__init__.py,sha256=PV3u5ZmhyfcHbKqySgwVA8m4-naZgxzydLXSBqdTGLM,1171
22
- climate_ref/datasets/base.py,sha256=uZ55u625ckRNjsn-AqJg4_xO5uvHchqYvwBZIt4iHtY,11017
23
- climate_ref/datasets/cmip6.py,sha256=KO761ConHvX40n9X0xLrxjhzN7wmighNWL2JyYygRAA,7049
24
- climate_ref/datasets/cmip6_parsers.py,sha256=wH4WKQAR2_aniXwsW7nch6nIpXk2pSpPxkT4unjV4hQ,6041
25
- climate_ref/datasets/obs4mips.py,sha256=q0_erQb4k5KBaGMvEGgUtVSDvXQjuftqDmvW4QZpWZI,6138
26
- climate_ref/datasets/pmp_climatology.py,sha256=goHDc_3B2Wdiy_hmpERNvWDdDYZACPOyFDt3Du6nGc0,534
27
- climate_ref/datasets/utils.py,sha256=iLJO7h4G3DWsRe9hIC4qkIyi5_zIW1ZMw-FDASLujtM,359
28
- climate_ref/executor/__init__.py,sha256=PYtJs3oBS_GiUHbt8BF-6wJibpF6_vREm1Cg9TxVbLI,648
29
- climate_ref/executor/hpc.py,sha256=ZhGtzM0skH_ojnkSc6UNYIetXoyBRCwfXJusuezBZGw,13876
30
- climate_ref/executor/local.py,sha256=65LUl41YtURFb87YTWZQHjDpIRlIKJ5Ny51c9DZjy0s,8582
31
- climate_ref/executor/pbs_scheduler.py,sha256=WoH1sTmDl7bdmYodpcxZjkUSvInYUcWR4x7buIgBxqk,5807
32
- climate_ref/executor/result_handling.py,sha256=i7ZMX5vvyPY5gW-WWd-JHLi1BLviB9FXhn4FE8C9d4w,7787
33
- climate_ref/executor/synchronous.py,sha256=o4TndsoKMu9AzJYLkusU9lRkgHCy6HcCP46tEs6o86U,1895
34
- climate_ref/migrations/README,sha256=xM5osYbyEbEFA2eh5kwary_oh-5VFWtDubA-vgWwvlE,935
35
- climate_ref/migrations/env.py,sha256=8GvBLhGTuQy6MKYMj7QszJEQ2LNewf1Z9kB9dBHQs9I,4375
36
- climate_ref/migrations/script.py.mako,sha256=MEqL-2qATlST9TAOeYgscMn1uy6HUS9NFvDgl93dMj8,635
37
- climate_ref/migrations/versions/2025-05-02T1418_341a4aa2551e_regenerate.py,sha256=S8Q4THCI4TPnlaQHgQJUCiNW5LAyQClaiTB-0dwhtXU,14050
38
- climate_ref/migrations/versions/2025-05-09T2032_03dbb4998e49_series_metric_value.py,sha256=s9nZ_l64pSF7sWN53rRPCQlqW_xHqR8tlWhU-ovmsME,2043
39
- climate_ref/migrations/versions/2025-07-03T1505_795c1e6cf496_drop_unique_requirement_on_slug.py,sha256=TfBHJkm3oPlz0P5Z1tiY6LBp2B1oDvdyL_OOYoV-OiI,984
40
- climate_ref/migrations/versions/2025-07-20T1521_94beace57a9c_cmip6_finalised.py,sha256=NSCMMV65v48B8_OoEf4X4bRthAlhzbDo0UlC6nqW3qs,2908
41
- climate_ref/migrations/versions/2025-08-05T0327_a1b2c3d4e5f6_finalised_on_base_dataset.py,sha256=G-SZKdU9dx9WyMh4JLwPKcud4gtFrxu-tULXG9vXGAU,2034
42
- climate_ref/models/__init__.py,sha256=rUDKRANeAEAHVOrzJVIZoZ99dDG5O4AGzHmOpC876Nc,801
43
- climate_ref/models/base.py,sha256=YMyovT2Z_tRv59zz6qC9YCCDodhO3x6OLnFdBtPJkho,1271
44
- climate_ref/models/dataset.py,sha256=in9FNLR4K_bpVSlWlk6A6IyFtkFy2v8ZFNcDXbwSMWI,8078
45
- climate_ref/models/diagnostic.py,sha256=0mKVvASEWNxx41R2Y-5VxplarZ4JAP6q0oaO14FKZuk,1751
46
- climate_ref/models/execution.py,sha256=lRCpaKLSR7rZbuoL94GW76tm9wLMsSDoIOA7bIa6xgY,9848
47
- climate_ref/models/metric_value.py,sha256=44OLcZz-qLx-p_9w7YWDKpD5S7Y9HyTKKsvSb77RBro,10190
48
- climate_ref/models/provider.py,sha256=RAE2qAAxwObu-72CdK4kt5ACMmKYEn07WJm7DU9hF28,990
49
- climate_ref-0.6.5.dist-info/METADATA,sha256=uKVSOC5iN1SGV3eoQ9uClB1UC_FpDbbM2ArYL0EHd0U,4505
50
- climate_ref-0.6.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
51
- climate_ref-0.6.5.dist-info/entry_points.txt,sha256=IaggEJlDIhoYWXdXJafacWbWtCcoEqUKceP1qD7_7vU,44
52
- climate_ref-0.6.5.dist-info/licenses/LICENCE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
53
- climate_ref-0.6.5.dist-info/licenses/NOTICE,sha256=4qTlax9aX2-mswYJuVrLqJ9jK1IkN5kSBqfVvYLF3Ws,128
54
- climate_ref-0.6.5.dist-info/RECORD,,