axsdb 0.0.2__py3-none-any.whl → 0.0.3__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.
- axsdb/core.py +40 -31
- axsdb/factory.py +3 -2
- axsdb/interpolation.py +803 -0
- axsdb/math.py +503 -0
- axsdb/testing/__init__.py +0 -0
- axsdb/testing/fixtures.py +77 -0
- {axsdb-0.0.2.dist-info → axsdb-0.0.3.dist-info}/METADATA +7 -5
- axsdb-0.0.3.dist-info/RECORD +17 -0
- {axsdb-0.0.2.dist-info → axsdb-0.0.3.dist-info}/WHEEL +1 -1
- axsdb-0.0.2.dist-info/RECORD +0 -13
- {axsdb-0.0.2.dist-info → axsdb-0.0.3.dist-info}/entry_points.txt +0 -0
axsdb/core.py
CHANGED
|
@@ -7,8 +7,9 @@ import logging
|
|
|
7
7
|
import os
|
|
8
8
|
import re
|
|
9
9
|
import textwrap
|
|
10
|
+
from collections.abc import Callable, Hashable
|
|
10
11
|
from pathlib import Path
|
|
11
|
-
from typing import Any,
|
|
12
|
+
from typing import Any, Literal
|
|
12
13
|
|
|
13
14
|
import attrs
|
|
14
15
|
import numpy as np
|
|
@@ -23,6 +24,7 @@ from .error import (
|
|
|
23
24
|
ErrorHandlingConfiguration,
|
|
24
25
|
get_error_handling_config,
|
|
25
26
|
)
|
|
27
|
+
from .interpolation import interp_dataarray
|
|
26
28
|
from .typing import PathLike
|
|
27
29
|
from .units import ensure_units, ureg, xarray_to_quantity
|
|
28
30
|
|
|
@@ -634,25 +636,7 @@ class AbsorptionDatabase:
|
|
|
634
636
|
thermoprops: xr.Dataset,
|
|
635
637
|
error_handling_config: ErrorHandlingConfiguration,
|
|
636
638
|
) -> tuple[xr.DataArray, list[Hashable]]:
|
|
637
|
-
#
|
|
638
|
-
bounds_error = error_handling_config.t.bounds is ErrorHandlingAction.RAISE
|
|
639
|
-
fill_value = None if bounds_error else 0.0 # TODO: use 2-element tuple?
|
|
640
|
-
result = da.interp(
|
|
641
|
-
t=thermoprops["t"],
|
|
642
|
-
kwargs={"bounds_error": bounds_error, "fill_value": fill_value},
|
|
643
|
-
)
|
|
644
|
-
|
|
645
|
-
# Interpolate on pressure
|
|
646
|
-
bounds_error = error_handling_config.p.bounds is ErrorHandlingAction.RAISE
|
|
647
|
-
fill_value = None if bounds_error else 0.0 # TODO: use 2-element tuple?
|
|
648
|
-
result = result.interp(
|
|
649
|
-
p=thermoprops["p"],
|
|
650
|
-
kwargs={"bounds_error": bounds_error, "fill_value": fill_value},
|
|
651
|
-
)
|
|
652
|
-
|
|
653
|
-
# Interpolate on concentrations
|
|
654
|
-
|
|
655
|
-
# -- List requested species concentrations
|
|
639
|
+
# List requested species concentrations
|
|
656
640
|
x_ds = [coord for coord in ds.coords if coord.startswith("x_")]
|
|
657
641
|
x_ds_scalar = [coord for coord in x_ds if ds[coord].size == 1]
|
|
658
642
|
x_ds_array = set(x_ds) - set(x_ds_scalar)
|
|
@@ -661,16 +645,41 @@ class AbsorptionDatabase:
|
|
|
661
645
|
x_missing = set(x_ds_array) - set(x_thermoprops)
|
|
662
646
|
x_ds_array = x_ds_array - x_missing
|
|
663
647
|
|
|
664
|
-
#
|
|
665
|
-
result =
|
|
666
|
-
|
|
667
|
-
#
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
thermoprops[
|
|
672
|
-
|
|
648
|
+
# Select on scalar coordinates and missing concentrations
|
|
649
|
+
result = da.isel(**{x: 0 for x in x_ds_scalar + list(x_missing)})
|
|
650
|
+
|
|
651
|
+
# Build interpolation parameters
|
|
652
|
+
coords = {"t": thermoprops["t"], "p": thermoprops["p"]}
|
|
653
|
+
|
|
654
|
+
for x in x_ds_array:
|
|
655
|
+
coords[x] = thermoprops[x]
|
|
656
|
+
|
|
657
|
+
bounds = {
|
|
658
|
+
"t": (
|
|
659
|
+
"raise"
|
|
660
|
+
if error_handling_config.t.bounds is ErrorHandlingAction.RAISE
|
|
661
|
+
else "fill"
|
|
662
|
+
),
|
|
663
|
+
"p": (
|
|
664
|
+
"raise"
|
|
665
|
+
if error_handling_config.p.bounds is ErrorHandlingAction.RAISE
|
|
666
|
+
else "fill"
|
|
667
|
+
),
|
|
668
|
+
}
|
|
669
|
+
x_bounds = (
|
|
670
|
+
"raise"
|
|
671
|
+
if error_handling_config.x.bounds is ErrorHandlingAction.RAISE
|
|
672
|
+
else "fill"
|
|
673
673
|
)
|
|
674
|
+
for x in x_ds_array:
|
|
675
|
+
bounds[x] = x_bounds
|
|
676
|
+
|
|
677
|
+
# Use fill_value=0.0 for all dimensions when not raising
|
|
678
|
+
# TODO: use 2-tuple?
|
|
679
|
+
fill_value = {dim: 0.0 for dim in coords}
|
|
680
|
+
|
|
681
|
+
# Perform interpolation
|
|
682
|
+
result = interp_dataarray(result, coords, bounds=bounds, fill_value=fill_value)
|
|
674
683
|
|
|
675
684
|
return result, x_ds
|
|
676
685
|
|
|
@@ -756,7 +765,7 @@ class MonoAbsorptionDatabase(AbsorptionDatabase):
|
|
|
756
765
|
)
|
|
757
766
|
|
|
758
767
|
# Drop thermophysical coordinates, ensure spectral dimension
|
|
759
|
-
result = result.drop_vars(["p", "t", *x_ds])
|
|
768
|
+
result = result.drop_vars(["p", "t", *x_ds], errors="ignore")
|
|
760
769
|
if "w" not in result.dims:
|
|
761
770
|
result = result.expand_dims("w")
|
|
762
771
|
|
|
@@ -859,7 +868,7 @@ class CKDAbsorptionDatabase(AbsorptionDatabase):
|
|
|
859
868
|
)
|
|
860
869
|
|
|
861
870
|
# Drop thermophysical coordinates, ensure spectral dimension
|
|
862
|
-
result = result.drop_vars(["p", "t", *x_ds])
|
|
871
|
+
result = result.drop_vars(["p", "t", *x_ds], errors="ignore")
|
|
863
872
|
if "w" not in result.dims:
|
|
864
873
|
result = result.expand_dims("w")
|
|
865
874
|
|
axsdb/factory.py
CHANGED
|
@@ -2,12 +2,13 @@ from __future__ import annotations
|
|
|
2
2
|
from pathlib import Path
|
|
3
3
|
|
|
4
4
|
import attrs
|
|
5
|
-
from
|
|
5
|
+
from collections.abc import Callable
|
|
6
|
+
from typing import Any, TYPE_CHECKING
|
|
6
7
|
|
|
7
8
|
if TYPE_CHECKING:
|
|
8
9
|
from axsdb import AbsorptionDatabase
|
|
9
10
|
|
|
10
|
-
AbsorptionDatabaseT =
|
|
11
|
+
AbsorptionDatabaseT = type[AbsorptionDatabase]
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
@attrs.define
|