climate-ref 0.5.0__py3-none-any.whl → 0.5.1__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.
- climate_ref/cli/__init__.py +18 -8
- climate_ref/cli/datasets.py +31 -27
- climate_ref/cli/executions.py +1 -1
- climate_ref/cli/providers.py +2 -4
- climate_ref/cli/solve.py +1 -2
- climate_ref/config.py +5 -6
- climate_ref/constants.py +1 -1
- climate_ref/database.py +1 -0
- climate_ref/dataset_registry/sample_data.txt +14 -0
- climate_ref/datasets/base.py +43 -39
- climate_ref/executor/__init__.py +4 -262
- climate_ref/executor/local.py +170 -37
- climate_ref/executor/result_handling.py +231 -0
- climate_ref/executor/synchronous.py +62 -0
- climate_ref/migrations/env.py +1 -0
- climate_ref/migrations/versions/2025-05-02T1418_341a4aa2551e_regenerate.py +0 -21
- climate_ref/migrations/versions/2025-05-09T2032_03dbb4998e49_series_metric_value.py +57 -0
- climate_ref/models/__init__.py +3 -1
- climate_ref/models/base.py +2 -0
- climate_ref/models/metric_value.py +138 -13
- climate_ref/provider_registry.py +1 -1
- climate_ref/solver.py +18 -30
- climate_ref/testing.py +11 -7
- {climate_ref-0.5.0.dist-info → climate_ref-0.5.1.dist-info}/METADATA +3 -1
- climate_ref-0.5.1.dist-info/RECORD +47 -0
- climate_ref-0.5.0.dist-info/RECORD +0 -44
- {climate_ref-0.5.0.dist-info → climate_ref-0.5.1.dist-info}/WHEEL +0 -0
- {climate_ref-0.5.0.dist-info → climate_ref-0.5.1.dist-info}/entry_points.txt +0 -0
- {climate_ref-0.5.0.dist-info → climate_ref-0.5.1.dist-info}/licenses/LICENCE +0 -0
- {climate_ref-0.5.0.dist-info → climate_ref-0.5.1.dist-info}/licenses/NOTICE +0 -0
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import enum
|
|
2
|
+
from collections.abc import Mapping
|
|
1
3
|
from typing import TYPE_CHECKING, Any, ClassVar
|
|
2
4
|
|
|
3
5
|
from loguru import logger
|
|
4
|
-
from sqlalchemy import Column, ForeignKey, Text
|
|
6
|
+
from sqlalchemy import Column, ForeignKey, Text, event
|
|
5
7
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
|
6
8
|
|
|
7
9
|
from climate_ref.models.base import Base, CreatedUpdatedMixin
|
|
@@ -11,9 +13,23 @@ if TYPE_CHECKING:
|
|
|
11
13
|
from climate_ref.models.execution import Execution
|
|
12
14
|
|
|
13
15
|
|
|
16
|
+
class MetricValueType(enum.Enum):
|
|
17
|
+
"""
|
|
18
|
+
Type of metric value
|
|
19
|
+
|
|
20
|
+
This is used to determine how the metric value should be interpreted.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
# The value is a single number
|
|
24
|
+
SCALAR = "scalar"
|
|
25
|
+
|
|
26
|
+
# The value is a list of numbers
|
|
27
|
+
SERIES = "series"
|
|
28
|
+
|
|
29
|
+
|
|
14
30
|
class MetricValue(CreatedUpdatedMixin, Base):
|
|
15
31
|
"""
|
|
16
|
-
Represents a single
|
|
32
|
+
Represents a single metric value
|
|
17
33
|
|
|
18
34
|
This value has a number of dimensions which are used to query the diagnostic value.
|
|
19
35
|
These dimensions describe aspects such as the type of statistic being measured,
|
|
@@ -26,14 +42,24 @@ class MetricValue(CreatedUpdatedMixin, Base):
|
|
|
26
42
|
|
|
27
43
|
__tablename__ = "metric_value"
|
|
28
44
|
|
|
45
|
+
__mapper_args__: ClassVar[Mapping[str, str]] = { # type: ignore
|
|
46
|
+
"polymorphic_on": "type",
|
|
47
|
+
}
|
|
48
|
+
|
|
29
49
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
30
50
|
execution_id: Mapped[int] = mapped_column(ForeignKey("execution.id"))
|
|
31
51
|
|
|
32
|
-
value: Mapped[float] = mapped_column()
|
|
33
52
|
attributes: Mapped[dict[str, Any]] = mapped_column()
|
|
34
53
|
|
|
35
54
|
execution: Mapped["Execution"] = relationship(back_populates="values")
|
|
36
55
|
|
|
56
|
+
type: Mapped[MetricValueType] = mapped_column()
|
|
57
|
+
"""
|
|
58
|
+
Type of metric value
|
|
59
|
+
|
|
60
|
+
This value is used to determine how the metric value should be interpreted.
|
|
61
|
+
"""
|
|
62
|
+
|
|
37
63
|
_cv_dimensions: ClassVar[list[str]] = []
|
|
38
64
|
|
|
39
65
|
@property
|
|
@@ -55,13 +81,7 @@ class MetricValue(CreatedUpdatedMixin, Base):
|
|
|
55
81
|
return dims
|
|
56
82
|
|
|
57
83
|
def __repr__(self) -> str:
|
|
58
|
-
return
|
|
59
|
-
f"<MetricValue "
|
|
60
|
-
f"id={self.id} "
|
|
61
|
-
f"execution={self.execution} "
|
|
62
|
-
f"value={self.value} "
|
|
63
|
-
f"dimensions={self.dimensions}>"
|
|
64
|
-
)
|
|
84
|
+
return f"<MetricValue id={self.id} execution={self.execution} dimensions={self.dimensions}>"
|
|
65
85
|
|
|
66
86
|
@staticmethod
|
|
67
87
|
def build_dimension_column(dimension: Dimension) -> Column[str]:
|
|
@@ -143,7 +163,22 @@ class MetricValue(CreatedUpdatedMixin, Base):
|
|
|
143
163
|
for key in keys:
|
|
144
164
|
cls._cv_dimensions.remove(key)
|
|
145
165
|
|
|
146
|
-
assert not len(cls._cv_dimensions)
|
|
166
|
+
assert not len(cls._cv_dimensions)
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
class ScalarMetricValue(MetricValue):
|
|
170
|
+
"""
|
|
171
|
+
A scalar value with an associated dimensions
|
|
172
|
+
|
|
173
|
+
This is a subclass of MetricValue that is used to represent a scalar value.
|
|
174
|
+
"""
|
|
175
|
+
|
|
176
|
+
__mapper_args__: ClassVar[Mapping[str, Any]] = { # type: ignore
|
|
177
|
+
"polymorphic_identity": MetricValueType.SCALAR,
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
# This is a scalar value
|
|
181
|
+
value: Mapped[float] = mapped_column(nullable=True)
|
|
147
182
|
|
|
148
183
|
@classmethod
|
|
149
184
|
def build(
|
|
@@ -158,7 +193,7 @@ class MetricValue(CreatedUpdatedMixin, Base):
|
|
|
158
193
|
Build a MetricValue from a collection of dimensions and a value
|
|
159
194
|
|
|
160
195
|
This is a helper method that validates the dimensions supplied and provides an interface
|
|
161
|
-
similar to [climate_ref_core.
|
|
196
|
+
similar to [climate_ref_core.metric_values.ScalarMetricValue][].
|
|
162
197
|
|
|
163
198
|
Parameters
|
|
164
199
|
----------
|
|
@@ -187,9 +222,99 @@ class MetricValue(CreatedUpdatedMixin, Base):
|
|
|
187
222
|
if k not in cls._cv_dimensions:
|
|
188
223
|
raise KeyError(f"Unknown dimension column '{k}'")
|
|
189
224
|
|
|
190
|
-
return
|
|
225
|
+
return ScalarMetricValue(
|
|
191
226
|
execution_id=execution_id,
|
|
192
227
|
value=value,
|
|
193
228
|
attributes=attributes,
|
|
194
229
|
**dimensions,
|
|
195
230
|
)
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
class SeriesMetricValue(MetricValue):
|
|
234
|
+
"""
|
|
235
|
+
A scalar value with an associated dimensions
|
|
236
|
+
|
|
237
|
+
This is a subclass of MetricValue that is used to represent a scalar value.
|
|
238
|
+
"""
|
|
239
|
+
|
|
240
|
+
__mapper_args__: ClassVar[Mapping[str, Any]] = { # type: ignore
|
|
241
|
+
"polymorphic_identity": MetricValueType.SERIES,
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
# This is a scalar value
|
|
245
|
+
values: Mapped[list[float | int]] = mapped_column(nullable=True)
|
|
246
|
+
index: Mapped[list[float | int | str]] = mapped_column(nullable=True)
|
|
247
|
+
index_name: Mapped[str] = mapped_column(nullable=True)
|
|
248
|
+
|
|
249
|
+
@classmethod
|
|
250
|
+
def build( # noqa: PLR0913
|
|
251
|
+
cls,
|
|
252
|
+
*,
|
|
253
|
+
execution_id: int,
|
|
254
|
+
values: list[float | int],
|
|
255
|
+
index: list[float | int | str],
|
|
256
|
+
index_name: str,
|
|
257
|
+
dimensions: dict[str, str],
|
|
258
|
+
attributes: dict[str, Any] | None,
|
|
259
|
+
) -> "MetricValue":
|
|
260
|
+
"""
|
|
261
|
+
Build a database object from a series
|
|
262
|
+
|
|
263
|
+
Parameters
|
|
264
|
+
----------
|
|
265
|
+
execution_id
|
|
266
|
+
Execution that created the diagnostic value
|
|
267
|
+
values
|
|
268
|
+
1-d array of values
|
|
269
|
+
index
|
|
270
|
+
1-d array of index values
|
|
271
|
+
index_name
|
|
272
|
+
Name of the index. Used for presentation purposes
|
|
273
|
+
dimensions
|
|
274
|
+
Dimensions that describe the diagnostic execution result
|
|
275
|
+
attributes
|
|
276
|
+
Optional additional attributes to describe the value,
|
|
277
|
+
but are not in the controlled vocabulary.
|
|
278
|
+
|
|
279
|
+
Raises
|
|
280
|
+
------
|
|
281
|
+
KeyError
|
|
282
|
+
If an unknown dimension was supplied.
|
|
283
|
+
|
|
284
|
+
Dimensions must exist in the controlled vocabulary.
|
|
285
|
+
ValueError
|
|
286
|
+
If the length of values and index do not match.
|
|
287
|
+
|
|
288
|
+
Returns
|
|
289
|
+
-------
|
|
290
|
+
Newly created MetricValue
|
|
291
|
+
"""
|
|
292
|
+
for k in dimensions:
|
|
293
|
+
if k not in cls._cv_dimensions:
|
|
294
|
+
raise KeyError(f"Unknown dimension column '{k}'")
|
|
295
|
+
|
|
296
|
+
if len(values) != len(index):
|
|
297
|
+
raise ValueError(f"Index length ({len(index)}) must match values length ({len(values)})")
|
|
298
|
+
|
|
299
|
+
return SeriesMetricValue(
|
|
300
|
+
execution_id=execution_id,
|
|
301
|
+
values=values,
|
|
302
|
+
index=index,
|
|
303
|
+
index_name=index_name,
|
|
304
|
+
attributes=attributes,
|
|
305
|
+
**dimensions,
|
|
306
|
+
)
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
@event.listens_for(SeriesMetricValue, "before_insert")
|
|
310
|
+
@event.listens_for(SeriesMetricValue, "before_update")
|
|
311
|
+
def validate_series_lengths(mapper: Any, connection: Any, target: SeriesMetricValue) -> None:
|
|
312
|
+
"""
|
|
313
|
+
Validate that values and index have matching lengths
|
|
314
|
+
|
|
315
|
+
This is done on insert and update to ensure that the database is consistent.
|
|
316
|
+
"""
|
|
317
|
+
if target.values is not None and target.index is not None and len(target.values) != len(target.index):
|
|
318
|
+
raise ValueError(
|
|
319
|
+
f"Index length ({len(target.index)}) must match values length ({len(target.values)})"
|
|
320
|
+
)
|
climate_ref/provider_registry.py
CHANGED
climate_ref/solver.py
CHANGED
|
@@ -25,21 +25,16 @@ from climate_ref.models import Provider as ProviderModel
|
|
|
25
25
|
from climate_ref.models.execution import Execution
|
|
26
26
|
from climate_ref.provider_registry import ProviderRegistry
|
|
27
27
|
from climate_ref_core.constraints import apply_constraint
|
|
28
|
-
from climate_ref_core.datasets import
|
|
28
|
+
from climate_ref_core.datasets import (
|
|
29
|
+
DatasetCollection,
|
|
30
|
+
ExecutionDatasetCollection,
|
|
31
|
+
Selector,
|
|
32
|
+
SourceDatasetType,
|
|
33
|
+
)
|
|
29
34
|
from climate_ref_core.diagnostics import DataRequirement, Diagnostic, ExecutionDefinition
|
|
30
35
|
from climate_ref_core.exceptions import InvalidDiagnosticException
|
|
31
36
|
from climate_ref_core.providers import DiagnosticProvider
|
|
32
37
|
|
|
33
|
-
SelectorKey = tuple[tuple[str, str], ...]
|
|
34
|
-
"""
|
|
35
|
-
Type describing the key used to identify a group of datasets
|
|
36
|
-
|
|
37
|
-
This is a tuple of tuples, where each inner tuple contains a metadata and dimension value
|
|
38
|
-
that was used to group the datasets together.
|
|
39
|
-
|
|
40
|
-
This SelectorKey type must be hashable, as it is used as a key in a dictionary.
|
|
41
|
-
"""
|
|
42
|
-
|
|
43
38
|
|
|
44
39
|
@frozen
|
|
45
40
|
class DiagnosticExecution:
|
|
@@ -81,20 +76,14 @@ class DiagnosticExecution:
|
|
|
81
76
|
return "__".join(key_values)
|
|
82
77
|
|
|
83
78
|
@property
|
|
84
|
-
def selectors(self) -> dict[str,
|
|
79
|
+
def selectors(self) -> dict[str, Selector]:
|
|
85
80
|
"""
|
|
86
81
|
Collection of selectors used to identify the datasets
|
|
87
82
|
|
|
88
83
|
These are the key, value pairs that were selected during the initial group-by,
|
|
89
84
|
for each data requirement.
|
|
90
85
|
"""
|
|
91
|
-
|
|
92
|
-
s = {}
|
|
93
|
-
for source_type in SourceDatasetType.ordered():
|
|
94
|
-
if source_type not in self.datasets:
|
|
95
|
-
continue
|
|
96
|
-
s[source_type.value] = self.datasets[source_type].selector
|
|
97
|
-
return s
|
|
86
|
+
return self.datasets.selectors
|
|
98
87
|
|
|
99
88
|
def build_execution_definition(self, output_root: pathlib.Path) -> ExecutionDefinition:
|
|
100
89
|
"""
|
|
@@ -107,6 +96,7 @@ class DiagnosticExecution:
|
|
|
107
96
|
fragment = pathlib.Path() / self.provider.slug / self.diagnostic.slug / self.datasets.hash
|
|
108
97
|
|
|
109
98
|
return ExecutionDefinition(
|
|
99
|
+
diagnostic=self.diagnostic,
|
|
110
100
|
root_directory=output_root,
|
|
111
101
|
output_directory=output_root / fragment,
|
|
112
102
|
key=self.dataset_key,
|
|
@@ -116,7 +106,7 @@ class DiagnosticExecution:
|
|
|
116
106
|
|
|
117
107
|
def extract_covered_datasets(
|
|
118
108
|
data_catalog: pd.DataFrame, requirement: DataRequirement
|
|
119
|
-
) -> dict[
|
|
109
|
+
) -> dict[Selector, pd.DataFrame]:
|
|
120
110
|
"""
|
|
121
111
|
Determine the different diagnostic executions that should be performed with the current data catalog
|
|
122
112
|
"""
|
|
@@ -140,8 +130,8 @@ def extract_covered_datasets(
|
|
|
140
130
|
|
|
141
131
|
for name, group in groups:
|
|
142
132
|
if requirement.group_by is None:
|
|
143
|
-
assert len(groups) == 1
|
|
144
|
-
group_keys:
|
|
133
|
+
assert len(groups) == 1
|
|
134
|
+
group_keys: Selector = ()
|
|
145
135
|
else:
|
|
146
136
|
group_keys = tuple(zip(requirement.group_by, name))
|
|
147
137
|
constrained_group = _process_group_constraints(data_catalog, group, requirement)
|
|
@@ -238,12 +228,12 @@ def _solve_from_data_requirements(
|
|
|
238
228
|
diagnostic=diagnostic,
|
|
239
229
|
datasets=ExecutionDatasetCollection(
|
|
240
230
|
{
|
|
241
|
-
|
|
242
|
-
datasets=dataset_groups[
|
|
243
|
-
slug_column=get_dataset_adapter(
|
|
244
|
-
selector=
|
|
231
|
+
source_type: DatasetCollection(
|
|
232
|
+
datasets=dataset_groups[source_type][selector],
|
|
233
|
+
slug_column=get_dataset_adapter(source_type.value).slug_column,
|
|
234
|
+
selector=selector,
|
|
245
235
|
)
|
|
246
|
-
for
|
|
236
|
+
for source_type, selector in zip(dataset_groups.keys(), items)
|
|
247
237
|
}
|
|
248
238
|
),
|
|
249
239
|
)
|
|
@@ -341,7 +331,7 @@ def solve_required_executions(
|
|
|
341
331
|
|
|
342
332
|
# Use a transaction to make sure that the models
|
|
343
333
|
# are created correctly before potentially executing out of process
|
|
344
|
-
with db.session.begin(
|
|
334
|
+
with db.session.begin():
|
|
345
335
|
diagnostic = (
|
|
346
336
|
db.session.query(DiagnosticModel)
|
|
347
337
|
.join(DiagnosticModel.provider)
|
|
@@ -386,8 +376,6 @@ def solve_required_executions(
|
|
|
386
376
|
execution.register_datasets(db, definition.datasets)
|
|
387
377
|
|
|
388
378
|
executor.run(
|
|
389
|
-
provider=potential_execution.provider,
|
|
390
|
-
diagnostic=potential_execution.diagnostic,
|
|
391
379
|
definition=definition,
|
|
392
380
|
execution=execution,
|
|
393
381
|
)
|
climate_ref/testing.py
CHANGED
|
@@ -10,7 +10,7 @@ from loguru import logger
|
|
|
10
10
|
from climate_ref.config import Config
|
|
11
11
|
from climate_ref.database import Database
|
|
12
12
|
from climate_ref.executor import handle_execution_result
|
|
13
|
-
from climate_ref.models import Execution
|
|
13
|
+
from climate_ref.models import Execution, ExecutionGroup
|
|
14
14
|
from climate_ref_core.dataset_registry import dataset_registry_manager, fetch_all_files
|
|
15
15
|
from climate_ref_core.diagnostics import Diagnostic, ExecutionResult
|
|
16
16
|
from climate_ref_core.pycmec.metric import CMECMetric
|
|
@@ -26,7 +26,7 @@ def _determine_test_directory() -> Path | None:
|
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
TEST_DATA_DIR = _determine_test_directory()
|
|
29
|
-
SAMPLE_DATA_VERSION = "v0.5.
|
|
29
|
+
SAMPLE_DATA_VERSION = "v0.5.2"
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
def fetch_sample_data(force_cleanup: bool = False, symlink: bool = False) -> None:
|
|
@@ -82,10 +82,16 @@ def validate_result(diagnostic: Diagnostic, config: Config, result: ExecutionRes
|
|
|
82
82
|
This should only be used by the test suite as it will create a fake
|
|
83
83
|
database entry for the diagnostic execution result.
|
|
84
84
|
"""
|
|
85
|
-
# Add a fake
|
|
85
|
+
# Add a fake execution/execution group in the Database
|
|
86
86
|
database = Database.from_config(config)
|
|
87
|
+
execution_group = ExecutionGroup(
|
|
88
|
+
diagnostic_id=1, key=result.definition.key, dirty=True, selectors=result.definition.datasets.selectors
|
|
89
|
+
)
|
|
90
|
+
database.session.add(execution_group)
|
|
91
|
+
database.session.flush()
|
|
92
|
+
|
|
87
93
|
execution = Execution(
|
|
88
|
-
execution_group_id=
|
|
94
|
+
execution_group_id=execution_group.id,
|
|
89
95
|
dataset_hash=result.definition.datasets.hash,
|
|
90
96
|
output_fragment=str(result.definition.output_fragment()),
|
|
91
97
|
)
|
|
@@ -96,9 +102,7 @@ def validate_result(diagnostic: Diagnostic, config: Config, result: ExecutionRes
|
|
|
96
102
|
|
|
97
103
|
# Validate bundles
|
|
98
104
|
metric_bundle = CMECMetric.load_from_json(result.to_output_path(result.metric_bundle_filename))
|
|
99
|
-
assert diagnostic.facets == tuple(metric_bundle.DIMENSIONS.root["json_structure"])
|
|
100
|
-
metric_bundle.DIMENSIONS.root["json_structure"]
|
|
101
|
-
)
|
|
105
|
+
assert diagnostic.facets == tuple(metric_bundle.DIMENSIONS.root["json_structure"])
|
|
102
106
|
CMECOutput.load_from_json(result.to_output_path(result.output_bundle_filename))
|
|
103
107
|
|
|
104
108
|
# Create a fake log file if one doesn't exist
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: climate-ref
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.1
|
|
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
|
|
@@ -28,6 +28,7 @@ Requires-Dist: platformdirs>=4.3.6
|
|
|
28
28
|
Requires-Dist: setuptools>=75.8.0
|
|
29
29
|
Requires-Dist: sqlalchemy>=2.0.36
|
|
30
30
|
Requires-Dist: tomlkit>=0.13.2
|
|
31
|
+
Requires-Dist: tqdm>=4.67.1
|
|
31
32
|
Requires-Dist: typer>=0.12.5
|
|
32
33
|
Provides-Extra: celery
|
|
33
34
|
Requires-Dist: climate-ref-celery>=0.5.0; extra == 'celery'
|
|
@@ -36,6 +37,7 @@ Requires-Dist: climate-ref-esmvaltool>=0.5.0; extra == 'metrics'
|
|
|
36
37
|
Requires-Dist: climate-ref-ilamb>=0.5.0; extra == 'metrics'
|
|
37
38
|
Requires-Dist: climate-ref-pmp>=0.5.0; extra == 'metrics'
|
|
38
39
|
Provides-Extra: postgres
|
|
40
|
+
Requires-Dist: alembic-postgresql-enum>=1.7.0; extra == 'postgres'
|
|
39
41
|
Requires-Dist: psycopg2-binary>=2.9.2; extra == 'postgres'
|
|
40
42
|
Description-Content-Type: text/markdown
|
|
41
43
|
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
climate_ref/__init__.py,sha256=OJl5EnjLyEoCQpa0zQ8edV8EcU2YxBJ0xjermIlm9Bw,820
|
|
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=kvF1DOsMDwic_AZiG6IOZ1tWbrQfE0iRrK-uRn-mNDc,15028
|
|
5
|
+
climate_ref/constants.py,sha256=9RaNLgUSuQva7ki4eRW3TjOKeVP6T81QNiu0veB1zVk,111
|
|
6
|
+
climate_ref/database.py,sha256=LJ6s5qSPJz4yaCzNjJZ-Mw71hquhnx0IKW32VulkuIs,7293
|
|
7
|
+
climate_ref/provider_registry.py,sha256=0oVHQrnFenEQhCUqhrZAUnF6r83VCbXrQVbbo8Bh96c,4109
|
|
8
|
+
climate_ref/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
+
climate_ref/solver.py,sha256=_QteO9AP1FR-P0W7WzwgntMh4VvpMAkhn02ikw-KDf8,13625
|
|
10
|
+
climate_ref/testing.py,sha256=O36cliznD1sj04xmsqFgowCXC-CoVpfLFbSPfzZbshI,4105
|
|
11
|
+
climate_ref/cli/__init__.py,sha256=1SjCNQ2fV5GtQX_TS77rNlf0h_ECGAup58WYGlcOTTs,4112
|
|
12
|
+
climate_ref/cli/_utils.py,sha256=6bIb8zEVvzXyKpv8MG58T-T2L2jH-G8WNrOOGpz3uCw,1918
|
|
13
|
+
climate_ref/cli/config.py,sha256=8I6CLdqKgTu6yaASy-qG0T839Fc0lDZtLSZ6YCc4wOY,520
|
|
14
|
+
climate_ref/cli/datasets.py,sha256=4k5iSeft5klYKFPBPkmN9sw1RNT7WWp6eI2RPxPT-SM,7519
|
|
15
|
+
climate_ref/cli/executions.py,sha256=sZXyVFYWML5mD7dE8xlsqyunsrwOIweTBDEUKCjXEpo,6798
|
|
16
|
+
climate_ref/cli/providers.py,sha256=eS9IaQxW8zGxidr8TWt7thdMU5JH53u4T3xbcIe2C_E,2455
|
|
17
|
+
climate_ref/cli/solve.py,sha256=1_7Y2Cs6pVCk8Yz1n_NuVhi7WdhfNbtPicbyT804ttE,656
|
|
18
|
+
climate_ref/dataset_registry/obs4ref_reference.txt,sha256=1NodZd3tOS9Z1Afpb_Oq4obp4OGAFDSAwEl3FssPwAQ,251
|
|
19
|
+
climate_ref/dataset_registry/sample_data.txt,sha256=ZQ-bPuBkwaChSYtEVFamg97qu-76oiOVEWn7l9HWYDc,14746
|
|
20
|
+
climate_ref/datasets/__init__.py,sha256=PV3u5ZmhyfcHbKqySgwVA8m4-naZgxzydLXSBqdTGLM,1171
|
|
21
|
+
climate_ref/datasets/base.py,sha256=sgfR548rLZRNPIaZKKXmGp8E_dyoAW1NONZnuVbFXa0,8286
|
|
22
|
+
climate_ref/datasets/cmip6.py,sha256=Dhq97ow8OmTshDCaL7vfrwn83Nfi6SY8uxJHeY4ZDHk,6083
|
|
23
|
+
climate_ref/datasets/obs4mips.py,sha256=PQhI3QKlYA9L2d_MpnlcVrUn4irMG7Iu-II8l1ncjUs,7032
|
|
24
|
+
climate_ref/datasets/pmp_climatology.py,sha256=goHDc_3B2Wdiy_hmpERNvWDdDYZACPOyFDt3Du6nGc0,534
|
|
25
|
+
climate_ref/datasets/utils.py,sha256=iLJO7h4G3DWsRe9hIC4qkIyi5_zIW1ZMw-FDASLujtM,359
|
|
26
|
+
climate_ref/executor/__init__.py,sha256=DooN4jQudmLHyw24IfqNfWynfa1vEolLs-mZ7uY8O0k,604
|
|
27
|
+
climate_ref/executor/local.py,sha256=W62scL2UTtBurhYQz9hVIHrYiq9-FeMKRdnajqiohN0,7753
|
|
28
|
+
climate_ref/executor/result_handling.py,sha256=UxhOTTe1a1p1sU1mZuFTChvhz06CbjY_NFl9BuWYj48,7885
|
|
29
|
+
climate_ref/executor/synchronous.py,sha256=o4TndsoKMu9AzJYLkusU9lRkgHCy6HcCP46tEs6o86U,1895
|
|
30
|
+
climate_ref/migrations/README,sha256=xM5osYbyEbEFA2eh5kwary_oh-5VFWtDubA-vgWwvlE,935
|
|
31
|
+
climate_ref/migrations/env.py,sha256=I3anCdIHAZlYDXpTrAeHlNieLd7-0t_xknuG1tzgNWE,4252
|
|
32
|
+
climate_ref/migrations/script.py.mako,sha256=MEqL-2qATlST9TAOeYgscMn1uy6HUS9NFvDgl93dMj8,635
|
|
33
|
+
climate_ref/migrations/versions/2025-05-02T1418_341a4aa2551e_regenerate.py,sha256=S8Q4THCI4TPnlaQHgQJUCiNW5LAyQClaiTB-0dwhtXU,14050
|
|
34
|
+
climate_ref/migrations/versions/2025-05-09T2032_03dbb4998e49_series_metric_value.py,sha256=s9nZ_l64pSF7sWN53rRPCQlqW_xHqR8tlWhU-ovmsME,2043
|
|
35
|
+
climate_ref/models/__init__.py,sha256=rUDKRANeAEAHVOrzJVIZoZ99dDG5O4AGzHmOpC876Nc,801
|
|
36
|
+
climate_ref/models/base.py,sha256=YMyovT2Z_tRv59zz6qC9YCCDodhO3x6OLnFdBtPJkho,1271
|
|
37
|
+
climate_ref/models/dataset.py,sha256=Rpwrx0HqOJBHs4Sb4n6B0In__Uo0PqXSZKvZR-juGCg,7491
|
|
38
|
+
climate_ref/models/diagnostic.py,sha256=YB6xzbEXdpz2j-Ddf19RV8mAiWBrkmtRmiAEUV3tl4Q,1762
|
|
39
|
+
climate_ref/models/execution.py,sha256=lRCpaKLSR7rZbuoL94GW76tm9wLMsSDoIOA7bIa6xgY,9848
|
|
40
|
+
climate_ref/models/metric_value.py,sha256=44OLcZz-qLx-p_9w7YWDKpD5S7Y9HyTKKsvSb77RBro,10190
|
|
41
|
+
climate_ref/models/provider.py,sha256=RAE2qAAxwObu-72CdK4kt5ACMmKYEn07WJm7DU9hF28,990
|
|
42
|
+
climate_ref-0.5.1.dist-info/METADATA,sha256=nOjrD0Q5EZuPUJO3pnmtaRNEkYP-CWKnnn4Q6kh-VAU,4123
|
|
43
|
+
climate_ref-0.5.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
44
|
+
climate_ref-0.5.1.dist-info/entry_points.txt,sha256=IaggEJlDIhoYWXdXJafacWbWtCcoEqUKceP1qD7_7vU,44
|
|
45
|
+
climate_ref-0.5.1.dist-info/licenses/LICENCE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
46
|
+
climate_ref-0.5.1.dist-info/licenses/NOTICE,sha256=4qTlax9aX2-mswYJuVrLqJ9jK1IkN5kSBqfVvYLF3Ws,128
|
|
47
|
+
climate_ref-0.5.1.dist-info/RECORD,,
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
climate_ref/__init__.py,sha256=OJl5EnjLyEoCQpa0zQ8edV8EcU2YxBJ0xjermIlm9Bw,820
|
|
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=QW1HOLajC2Gc5xZnrGQ8YLAver3BAlVBrfl1kVd_IyM,15072
|
|
5
|
-
climate_ref/constants.py,sha256=rFk3XxNuP0lkzTvUneIhNLq16uadXsT45aUFIlSiBmg,111
|
|
6
|
-
climate_ref/database.py,sha256=RCffNHbJcxxukN6PIOXBTW9TALE2rRsxU0chJHxyNK4,7257
|
|
7
|
-
climate_ref/provider_registry.py,sha256=P35H4VFcsxJ8-Ly4Czwi_gelDU_nF5RiqSC-iBcx_Ws,4116
|
|
8
|
-
climate_ref/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
-
climate_ref/solver.py,sha256=Hpb_3g-hYWopuBYyqaEtOgfuLOHfZpWbwP1rco802uE,14310
|
|
10
|
-
climate_ref/testing.py,sha256=rUdtU8a4p2OV35IO87veW0mEB9C4Bqwe7BBQU6BILhs,3889
|
|
11
|
-
climate_ref/cli/__init__.py,sha256=RSzaFkgwn1qWRBVbWlDKtNrIxLvQ2T7IWDBIqptpjjU,3658
|
|
12
|
-
climate_ref/cli/_utils.py,sha256=6bIb8zEVvzXyKpv8MG58T-T2L2jH-G8WNrOOGpz3uCw,1918
|
|
13
|
-
climate_ref/cli/config.py,sha256=8I6CLdqKgTu6yaASy-qG0T839Fc0lDZtLSZ6YCc4wOY,520
|
|
14
|
-
climate_ref/cli/datasets.py,sha256=SLl88S3BxKPRbHy9OJ1ymhMnxDmkadFO_BZTIeLR0k8,7367
|
|
15
|
-
climate_ref/cli/executions.py,sha256=6cnMxPK4ZydscUw_Mk9RMISNjP2Yr98BgsOsei8fQ7w,6799
|
|
16
|
-
climate_ref/cli/providers.py,sha256=XVZQsZoEqiCBvgSmp6cNf0mCTxeq_Ycoc6DwVxWDYKg,2521
|
|
17
|
-
climate_ref/cli/solve.py,sha256=D6rAivfm_yl1TTey_zc4KKwZ96LGGF8N1wHjcJ_0XpE,703
|
|
18
|
-
climate_ref/dataset_registry/obs4ref_reference.txt,sha256=1NodZd3tOS9Z1Afpb_Oq4obp4OGAFDSAwEl3FssPwAQ,251
|
|
19
|
-
climate_ref/dataset_registry/sample_data.txt,sha256=aKl9tfO4vknZ5X2mmdyxKOv-nyWhkPDXnpDoNLLTzE8,11892
|
|
20
|
-
climate_ref/datasets/__init__.py,sha256=PV3u5ZmhyfcHbKqySgwVA8m4-naZgxzydLXSBqdTGLM,1171
|
|
21
|
-
climate_ref/datasets/base.py,sha256=XplxCu4bfFmNHp2q8tHT26lB0RHv5swK0QqfUmuMO-c,8154
|
|
22
|
-
climate_ref/datasets/cmip6.py,sha256=Dhq97ow8OmTshDCaL7vfrwn83Nfi6SY8uxJHeY4ZDHk,6083
|
|
23
|
-
climate_ref/datasets/obs4mips.py,sha256=PQhI3QKlYA9L2d_MpnlcVrUn4irMG7Iu-II8l1ncjUs,7032
|
|
24
|
-
climate_ref/datasets/pmp_climatology.py,sha256=goHDc_3B2Wdiy_hmpERNvWDdDYZACPOyFDt3Du6nGc0,534
|
|
25
|
-
climate_ref/datasets/utils.py,sha256=iLJO7h4G3DWsRe9hIC4qkIyi5_zIW1ZMw-FDASLujtM,359
|
|
26
|
-
climate_ref/executor/__init__.py,sha256=vUkE5Izfietvc57gA8LTdaD5IErKVebcE6qO7M7sCRo,9286
|
|
27
|
-
climate_ref/executor/local.py,sha256=3icom02FCHiN0tIpsXR9tvn8-cQrUyoY-LlbHapbTx4,2920
|
|
28
|
-
climate_ref/migrations/README,sha256=xM5osYbyEbEFA2eh5kwary_oh-5VFWtDubA-vgWwvlE,935
|
|
29
|
-
climate_ref/migrations/env.py,sha256=b8om-LvFhVo_2BgaRsR8LcPQ-YcevjWikaWE6uhScAs,4213
|
|
30
|
-
climate_ref/migrations/script.py.mako,sha256=MEqL-2qATlST9TAOeYgscMn1uy6HUS9NFvDgl93dMj8,635
|
|
31
|
-
climate_ref/migrations/versions/2025-05-02T1418_341a4aa2551e_regenerate.py,sha256=349kbd58NdFHqqUAPDX1kR9RUOcxT2zXh9v9yg9-Je8,15533
|
|
32
|
-
climate_ref/models/__init__.py,sha256=dFyqfhTffZz4m06xD4SyvRL9kIBRyVYetHwOxFGy4VM,713
|
|
33
|
-
climate_ref/models/base.py,sha256=cMjNpGNU7pxRi9A5KXEmQIA9pvQDwqGCwo539yndpGY,1199
|
|
34
|
-
climate_ref/models/dataset.py,sha256=Rpwrx0HqOJBHs4Sb4n6B0In__Uo0PqXSZKvZR-juGCg,7491
|
|
35
|
-
climate_ref/models/diagnostic.py,sha256=YB6xzbEXdpz2j-Ddf19RV8mAiWBrkmtRmiAEUV3tl4Q,1762
|
|
36
|
-
climate_ref/models/execution.py,sha256=lRCpaKLSR7rZbuoL94GW76tm9wLMsSDoIOA7bIa6xgY,9848
|
|
37
|
-
climate_ref/models/metric_value.py,sha256=Sfjem65ih9g6WDpjGsiOphSjhYQ1ZAYUPZmsKyb_psU,6452
|
|
38
|
-
climate_ref/models/provider.py,sha256=RAE2qAAxwObu-72CdK4kt5ACMmKYEn07WJm7DU9hF28,990
|
|
39
|
-
climate_ref-0.5.0.dist-info/METADATA,sha256=pTjBsQveKvV8KGgvD9fy8LoxQ5CS-1ruBoFM4ReeLvY,4028
|
|
40
|
-
climate_ref-0.5.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
41
|
-
climate_ref-0.5.0.dist-info/entry_points.txt,sha256=IaggEJlDIhoYWXdXJafacWbWtCcoEqUKceP1qD7_7vU,44
|
|
42
|
-
climate_ref-0.5.0.dist-info/licenses/LICENCE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
43
|
-
climate_ref-0.5.0.dist-info/licenses/NOTICE,sha256=4qTlax9aX2-mswYJuVrLqJ9jK1IkN5kSBqfVvYLF3Ws,128
|
|
44
|
-
climate_ref-0.5.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|